octave-maintainers
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Passing variables up to the GUI


From: Michael Goffioul
Subject: Re: Passing variables up to the GUI
Date: Sat, 13 Apr 2013 19:49:57 -0400

On Sat, Apr 13, 2013 at 3:29 PM, Daniel J Sebald <address@hidden> wrote:
Well, let's think about this.  How is this going to crash from a too deep reference count?  Would it be the case that if the worker thread (Octave core) keeps emitting signals while the GUI thread doesn't respond to them?  Is that the bad scenario you are describing?

The problem is very basic: 2 (or more) threads trying to access/modify the reference count of an object concurrently. The copy constructor of octave_value does:

    rep->count++;

The destructor of octave_value does:

    if (--rep->count == 0)
        delete rep;

Those operations are *not* atomic, this means that while one thread is incrementing the counter, another one is decrementing it. The result is undefined. The best case scenario, the counter never reaches 0 and you get a memory leak. Worst case scenario, you try to access an object that has been deleted and you get a crash.

There's not much you can do to prevent this, except making the operation (increment/decrement) on the counter atomic at the CPU level. This is typically what shared_ptr<> implementation does.

Another ad-hoc solution would be to have the emitter thread to keep a reference of the passed object, until it is sure that the receiver thread has finished with it (for instance by receiving a signal back). But even then, you might get into trouble, as you don't know where and when all existing references will be deleted: a queued signal must keep a reference somewhere to the passed objects, which get discarded at some point, but is it in the emitter thread or the receiver thread?
 
There is this option Qt::BlockingQueuedConnection that we could use. This runs the risk of, as you said, deadlocking the threads.  But that might be fine in this case so long as there is no ->exec() in the GUI event loop.  If the deadlocking is placed at moments where the GUI just accepts the data and stores it somewhere, builds a table, etc., I don't think that is too critical.  If just the connections that are requesting octave_value_list data are BlockingQueued, then these are the GUI routines that are just wanting some data and not much else.  I'm not sure using BlockingQueued is a good idea though in a complex system; not without some thought anyway.  There is too much risk of some other programmer putting in an ->exec () into the code not realizing that is bad.

Blocking calls in threads is probably a bad practice imo.

Michael.


reply via email to

[Prev in Thread] Current Thread [Next in Thread]