Nikolay Sivov nsivov@codeweavers.com writes:
+DWORD NTAPI RtlRunOnceExecuteOnce(PRTL_RUN_ONCE initonce, PRTL_RUN_ONCE_INIT_FN callback, void *parameter, void **ctxt) +{ +#ifdef __linux__
- if (!use_futexes()) return FALSE;
- for (;;)
- {
DWORD_PTR val = (DWORD_PTR)interlocked_cmpxchg_ptr( &initonce->Ptr, (void*)1, NULL );
switch (val & 0x3)
{
case 0:
{
DWORD ret = callback(initonce, parameter, ctxt);
if (ret)
{
DWORD_PTR context = ctxt ? (DWORD_PTR)*ctxt : 0;
context = (context & ~0x3) | 0x2;
interlocked_cmpxchg_ptr( &initonce->Ptr, (void*)context, (void*)1 );
}
else
interlocked_cmpxchg_ptr( &initonce->Ptr, NULL, (void*)1 );
futex_wake( (int *)&initonce->Ptr, 1 );
return ret;
}
case 1:
/* blocked by another thread */
futex_wait( (int *)&initonce->Ptr, 1, NULL );
break;
case 2:
/* already initialized */
return TRUE;
}
- }
It's supposed to return an NTSTATUS, not a boolean. Also you have to always return the context, and you should try to do a generic implementation first.