On Sat, 1 Sep 2001 11:18:47 +0200
"Sander Striker" <[EMAIL PROTECTED]> 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.