Re: gthread-win32.c
- From: Kaz Kylheku <kaz ashi footprints net>
- To: Steven Brooks <umbrook0 cs umanitoba ca>
- Cc: Sebastian Wilhelmi <wilhelmi ira uka de>, gtk-devel-list <gtk-devel-list gnome org>, Dan Maas <dmaas dcine com>
- Subject: Re: gthread-win32.c
- Date: Tue, 22 May 2001 12:25:45 -0700 (PDT)
On Tue, 22 May 2001, Steven Brooks wrote:
> Sebastian Wilhelmi wrote:
>
> > Hi Kaz, Dan, Steven and all interested parties.
> >
> > We now have a native thread implementation for win32. Everything was quite
> > straightforward once I got used to the different calling conventions in
> > windows (Argh....!). The only challange were the condition varibales. They are
> > modelled after what Kaz proposed, I think it's called "Explicit Notification".
> > Using GArrays instead of GLists they should be quite efficient....
> >
> > Please have a look to avoid any loopholes in this implementation.
> >
> > http://cvs.gnome.org/bonsai/cvsblame.cgi?file=glib/gthread/gthread-win32.c
> >
> > Thanks,
> > Sebastian
> >
>
> 234 if (retval == WAIT_TIMEOUT)
> 235 {
> 236 EnterCriticalSection (&cond->lock);
Beware that EnterCriticalSection can throw a low memory structured
exception, if it needs to allocate the internal auto-reset event
and the CreateEvent() fails. As a hack, it's possible to create an
auto-reset event, and store its handle into the critical section.
Been there, done that. On NT4 there is a variant called
InitializeCriticalSectionAndSpincount which will preallocate
the event if the spincount is 0x80000000 - 0x7FFFFFFF.
> 237 g_ptr_array_remove (cond->array, event);
> 238
> 239 /* In the meantime we could have been signaled,
> so we must again
> 240 * wait for the signal, this time with no
> timeout, to reset it */
> 241 win32_check_for_error (WAIT_FAILED !=
> WaitForSingleObject (event, 0));
> 242
> 243 LeaveCriticalSection (&cond->lock);
> 244 }
>
> Should this not change retval? If the object has been signalled, then
> it should return successful. Otherwise, the event which caused the
> object to be signalled is lost.
Absolutely. There are two requirements: one is that if a timeout and
signal happen about the same time, we want to make sure everything is
in a sane state. Then there is a secondary requirement that it would be
nice if the timeout would avoid ``eating'' the signal, because the
signal is more important. You can dispense with the second requirement,
but then the application programmer must treat every timeout as a
potential signal: record that the timeout happened, then re-test
the predicate and do what is necessary, then act on the timeout.
>
> 462 retval->thread = (HANDLE) _beginthreadex (NULL,
> stack_size, g_thread_proxy,
> 463 wilhelmi 1.1 retval, 0, &ignore);
>
> Interesting. Why not use CreateThread?
Because _beginthreadex uses CreateThread to routes your thread through
an internal threading function which sets up and cleans up
thread-specific storage related to Microsoft's C library. The cleanup
happens when your thread terminates by returning from its threading
function. But what if two separate libraries want to attach thread
specific storage to a thread?
It's all because of Microsoft's brain-damaged thread local storage
implementation, which doesn't have destructor functions unlike the
POSIX one. In the POSIX world, your software component can attach
thread-specific data to a thread without the need to override the
thread startup function. When the thread terminates, a registered
handler associated with the thread specific key will be invoked which
can clean up the thread specific resources. So a large number of
program modules can independently attach thread specific resources to a
thread.
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]