You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@apr.apache.org by Greg Marr <gr...@alum.wpi.edu> on 2001/09/01 18:29:53 UTC
Re: cvs commit: apr/threadproc/win32 thread.c
On Sat, 1 Sep 2001 11:18:47 +0200
"Sander Striker" <st...@apache.org> wrote:
> > rbb 01/09/01 00:29:07
> > APR_DECLARE(apr_status_t) apr_thread_once(apr_thread_once_t
> *control,
> > void (*func)(void))
> > {
> > + /* Quick escape hatch, and bug fix.
>
> This still isn't correct. Now we have a race condition that
> could result in the function never being called instead of once.
> This looks better IMHO:
>
> if (!InterlockedExchange(&control->value, 1))
> func();
>
> return APR_SUCCESS;
To also include the quick escape hatch:
/* Save the system call if InterlockedExchange can't possibly return 0.
The InterlockedExchange function returns the *old* value of the
variable. If it is 0, this is the first function to make it 1, and
so the function should be called. */
if ((0 == control->value) && (0 == InterlockedExchange(&control->value,
1)))
func();
return APR_SUCCESS;
BTW, I looked at doing this with InterlockedIncrement, since it returns
the new value, except that Win95 is broken, and it just returns non-zero
on success, not necessarily the new value.
RE: cvs commit: apr/threadproc/win32 thread.c
Posted by Sander Striker <st...@apache.org>.
> On Sat, 1 Sep 2001 11:18:47 +0200
> "Sander Striker" <st...@apache.org> wrote:
> > > rbb 01/09/01 00:29:07
> > > APR_DECLARE(apr_status_t) apr_thread_once(apr_thread_once_t
> > *control,
> > > void (*func)(void))
> > > {
> > > + /* Quick escape hatch, and bug fix.
> >
> > This still isn't correct. Now we have a race condition that
> > could result in the function never being called instead of once.
> > This looks better IMHO:
> >
> > if (!InterlockedExchange(&control->value, 1))
> > func();
> >
> > return APR_SUCCESS;
>
> To also include the quick escape hatch:
>
> /* Save the system call if InterlockedExchange can't possibly return 0.
> The InterlockedExchange function returns the *old* value of the
> variable. If it is 0, this is the first function to make it 1, and
> so the function should be called. */
> if ((0 == control->value) && (0 == InterlockedExchange(&control->value,
> 1)))
> func();
>
> return APR_SUCCESS;
>
> BTW, I looked at doing this with InterlockedIncrement, since it returns
> the new value, except that Win95 is broken, and it just returns non-zero
> on success, not necessarily the new value.
Check out:
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dllproc/hh/
winbase/synchro_1k38.asp
W95, NT3.51 and earlier do not neccesarily return the old value. Details,
details... :)
Sander