Re: gthread-win32.c



On Tue, 15 May 2001, Steven Brooks wrote:

> Date: Tue, 15 May 2001 11:34:56 -0500
> From: Steven Brooks <umbrook0 cs umanitoba ca>
> To: gtk-devel-list gnome org
> Subject: Re: gthread-win32.c
>
>  Dan Maas wrote:
>
> >>> static void
> >>> g_cond_broadcast_win32_impl (GCond * cond)
> >>> {
> >>>   /* XXX : signal all waiters ? */
> >>> }
> >>
> >>
> >> No way (that I know of) to do this in windows.  At least, not through
> >> the Win32 API.  An event created to auto-reset will always signal
> >> exactly one thread. An event created to manual-reset will always signal
> >> all threads.
> >
> >
> >
> > AFAIK it is actually possible to accomplish both wake-one and wake-all on
> > Windows, but writing a correct implementation with no race conditions is
> > *not* trivial and involves some overhead. I believe the Cygnus Win32
> > pthreads DLL does have a correct implementation, you may want to check
> > their
> > sources...
>
>
>  My suspicion is you need a thread to manage the other threads.  It uses
>  suspends and resumes to control them, and all event requests go through

There is no reliable way to control another thread with suspends and
resumes, because you have no idea what it's doing. This type of
technique is best left to debuggers and garbage collectors.

>  the management thread.  Definitely do-able, and as long as all event
>  requests (Set, Reset and Pulse) go through the thread, you can guarantee
>  correct semantics.

Note that PulseEvent is complete bullshit and should be forgotten
about.  It might have been vaguely useful once under cooperative
multitasking.  Basically it wakes up an unknown number of threads
without changing state. It might as well be called

    InsertLostWakeupRaceConditionHere();

The problem is that you have no idea whether the threads that should
wake up have actually reached the wait operation.

>  To guarantee cond_wait, you probably have to pipe the mutex requests
>  through that thread as well.

Conditions can be implemented using Win32 events without such a manager
thread.  There exist a number of approaches. Some clever techniques
were being discussed in comp.programming.threads recently.

One no-nonsense approach is to assign each thread its own auto-reset
event, and to implement a mechanism for queuing waiting threads.  To
wait on some object like a condition, a thread adds itself to the
object's queue, releases the lock and then waits on its own auto-reset
event.

Waking up all threads is done simply by copying out the queue,
unlocking it, and then iterating over it, signaling each thread's
auto-reset event.

Waking up a single thread is done by removing just one thread from the
queue, releasing the queue lock and hitting that thread's event.

Timed-out waits are slightly tricky; the thread needs to see whether it
is still enqueued upon waking up, so that the timed-out wakeup doesn't
``eat'' a signal.  If you implement cancelation as well, as I have,
there are some additional contortions. :)





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