diff options
author | Saúl Ibarra Corretgé <s@saghul.net> | 2024-03-25 11:57:52 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-03-25 11:57:52 +0100 |
commit | abc9767034d7c065e6a861cc398a580d0f94e24f (patch) | |
tree | 7648fc2e858991f7574b62977ce11c67ea1dd1ec /src | |
parent | 6adeeacee7eb997d60552351b43d65b494745700 (diff) | |
download | libuv-abc9767034d7c065e6a861cc398a580d0f94e24f.tar.gz libuv-abc9767034d7c065e6a861cc398a580d0f94e24f.zip |
win: simplify uv_once implementation
* win: simplify uv_once implementation
InitOnceExecuteOnce is available in Windows >= Vista.
Ref: https://learn.microsoft.com/en-us/windows/win32/api/synchapi/nf-synchapi-initonceexecuteonce
Diffstat (limited to 'src')
-rw-r--r-- | src/win/thread.c | 44 |
1 files changed, 11 insertions, 33 deletions
diff --git a/src/win/thread.c b/src/win/thread.c index 57c25e8f..bf39b886 100644 --- a/src/win/thread.c +++ b/src/win/thread.c @@ -32,45 +32,23 @@ #include "uv.h" #include "internal.h" -static void uv__once_inner(uv_once_t* guard, void (*callback)(void)) { - DWORD result; - HANDLE existing_event, created_event; - - created_event = CreateEvent(NULL, 1, 0, NULL); - if (created_event == 0) { - /* Could fail in a low-memory situation? */ - uv_fatal_error(GetLastError(), "CreateEvent"); - } +typedef void (*uv__once_cb)(void); - existing_event = InterlockedCompareExchangePointer(&guard->event, - created_event, - NULL); +typedef struct { + uv__once_cb callback; +} uv__once_data_t; - if (existing_event == NULL) { - /* We won the race */ - callback(); +static BOOL WINAPI uv__once_inner(INIT_ONCE *once, void* param, void** context) { + uv__once_data_t* data = param; - result = SetEvent(created_event); - assert(result); - guard->ran = 1; + data->callback(); - } else { - /* We lost the race. Destroy the event we created and wait for the existing - * one to become signaled. */ - CloseHandle(created_event); - result = WaitForSingleObject(existing_event, INFINITE); - assert(result == WAIT_OBJECT_0); - } + return TRUE; } - -void uv_once(uv_once_t* guard, void (*callback)(void)) { - /* Fast case - avoid WaitForSingleObject. */ - if (guard->ran) { - return; - } - - uv__once_inner(guard, callback); +void uv_once(uv_once_t* guard, uv__once_cb callback) { + uv__once_data_t data = { .callback = callback }; + InitOnceExecuteOnce(&guard->init_once, uv__once_inner, (void*) &data, NULL); } |