Re: [2/2] kernel32: Implement InitOnceExecuteOnce() for Linux platform (resend)
Nikolay Sivov <nsivov(a)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. -- Alexandre Julliard julliard(a)winehq.org
participants (1)
-
Alexandre Julliard