Re: glib win32 condvar implementation


I was looking over the gthread win32 implementation today when doing
some dbus threading work, and i noticed what i think is a bug:

In g_cond_wait_internal() we add the even to the event array in the
condvar, then we sleep on it. When we wake up or timeout we then remove
the event object from the array... Except we don't, we only do that in
the case of a timeout. I really think we always should remove it, and in
fact we should reset it always too, in case we got some extra wakeup
call inbetween.

The technique is as follows: all condition variables are implemented
as arrays, containing exactly one entry for every thread, waiting on
that condition variable. This entry is a handle to a thread specific
win32 Event. In g_cond_wait this entry is added to the array, and in
g_cond_signal it is removed, before sending enabling event. Thus
g_cond_wait only in case of a timeout has to be remove the entry from
the array.

This is done for two reasons. Firstly it is faster to remove the
entry, while transversing the array. Secondly (and more importantly)
it avoids the race condition, where an event is send twice by a
g_cond_signal, before g_cond_wait comes around to remove the entry.
This event will remain in the event queue and will thus be consumed by
the next g_cond_wait, even though no g_cond_signal is called.

/ Sebastian
Sebastian Wilhelmi
wilhelmi google com

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