Re: gthread-win32.c



On Tue, 22 May 2001, Dan Maas wrote:

> Date: Tue, 22 May 2001 14:23:16 -0400
> From: Dan Maas <dmaas dcine com>
> To: Steven Brooks <umbrook0 cs umanitoba ca>,
>      Sebastian Wilhelmi <wilhelmi ira uka de>
> Cc: gtk-devel-list <gtk-devel-list gnome org>,
>      Kaz Kylheku <kaz ashi footprints net>
> Subject: Re: gthread-win32.c
>
> > 227 g_mutex_unlock (entered_mutex);
> > 228
> > 229 win32_check_for_error (WAIT_FAILED !=
> > 230 (retval = WaitForSingleObject (event, milliseconds)));
> > 231
> > 232 wilhelmi 1.1 g_mutex_lock (entered_mutex);
> >
> >
> > Lines 227-230 should be ObjectSignalAndWait, if supported.
>
> Yes this is what we were discussing earlier... Lines 227 and 230 should be
> atomic, otherwise a wakeup could arrive between them, and the thread would
> sleep anyway.

Explain how that could happen if the wakeup is recorded by the
auto-reset event that is about to be waited on!

An auto-reset event is semantically equivalent to a binary semaphore (a
semaphore which counts from 0 to 1).

> As Steven said, you could detect Windows NT at startup and just use
> SignalObjectAndWait() here...

If a critical section is used for the mutex, you cannot do this,
because a critical section is not a regular handle.

> Actually, I wonder if it might be possible to
> avoid lost wakeups if the per-thread 'event' is a manual-reset event instead
> of an auto-reset event...

There are no lost wakeups to avoid when you have a per-thread event,
assuming you don't need to have more than one wakeup queued. This is
the case if each wakeup removes the thread from the wait queue, making
it ineligible for another wakeup until it processes that one and
re-registers in a wait queue again.

With a manual-reset event it wouldn't matter if
> the cond_broadcast/cond_signal came before this thread's
> WaitForSingleObject(), because the event would remain signalled...

A manual reset event would simply require more system calls. You would
call ResetEvent precisely in those circumstances in which the
auto-reset event would take care of it. Calling ResetEvent while the
thread is enqueued for a signal would actually *cause* a lost wakeup
problem. Manual reset events are dangerous for that reason, because
the reset operation, if inappropriately timed, might trample over a signal
that just happened.

So you would call ResetEvent() only when your thread is known to be no
longer waiting for a signal, in other words, immediately after
returning from the Wait operation---or, alternately, at the very start
of the condition wait before enqueuing.





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