Re: Race condition during Dispatcher deconstruction



On Mon, 2008-01-07 at 08:43 -0600, Matt Hoosier wrote:
> On Jan 7, 2008 1:07 AM, Daniel Elstner <daniel kitta googlemail com> wrote:
[snip]
> > If the Dispatcher is created and destroyed together with the widget
> > which registers the callback, then you did indeed hit the scenario
> > already described by Chris Vine.
> 
> Well, the application already does this. It seems like joining on the
> background thread has no effect here, because the "damage" is that the
> byte is already written to the pipe before the background thread
> exits. Then there's the Glib::signal_io() handler sitting out there
> waiting to fire on the UI thread's side of things, possibly after the
> Dispatcher has already been destructed.
> 
> I know that the DispatcherNotifier object attempts to avoid this by doing
> 
>   conn_io_handler_.disconnect()
> 
> in its own destructor, but the crash inside pipe_io_handler() after
> I'm certain that the destructor for the Dispatcher has run, makes me
> wonder if this isn't really disconnecting the GIOChannel underneath.

I cannot find conn_io_handler.disconnect() in the version of glibmm I
have installed (2.14.1).  I will need to look at this again but I
assumed your problem arises from the fact that (in 2.14.1 at least)
there is a single thread-local Glib::DispatchNotifier object for each
thread having a Glib::MainContext event loop (and most programs will
only have one of those), which any given Glib::Dispatcher will obtain
with a call to the static method
Glib::DispatchNotifier::reference_instance() - the first
Glib::Dispatcher object will create the DispatchNotifier object for the
thread and any subsequent ones created will increase the reference
count.

Provided that at least one Glib::Dispatcher object remains (that is, the
DispatchNotifier reference count is at least one) in the thread in
question, the receipt of data on the pipe will invoke the
Glib::DispatcherNotifier::pipe_io_handler() callback.  That callback
will extract a DispatchNotifierData object from the DispatcherNotifier
object's pipe, and it will proceed to call data.dispatcher->signal_().
If by the time that call is made the particular Dispatcher object which
has been invoked and its signal object no longer exist, a memory error
will arise.

Or is it more complicated than that?  It is late now but I will see if I
have missed something tomorrow.

Chris





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