[PATCH 1/2] compat/win32/pthread: add pthread_once()
- From
Matheus Tavares <matheus.bernardino@usp.br>
- Date
- Jun 25, 2020, 20:32 UTC
- Message-ID
- <e5a10d3f2152859b75bd815c37511975057d0ab0.1593115455.git.matheus.bernardino@usp.br>
- In-Reply-To
- <cover.1593115455.git.matheus.bernardino@usp.br>
Signed-off-by: Matheus Tavares <matheus.bernardino@usp.br> ---
Note: the pthread_once() function is adapted from: https://git.libav.org/?p=libav.git;a=commitdiff;h=b22693b06d1e5d73454a65c203b4d31c1ca5b69a
Which is LGPLv2.1. Should I add any notice/acknowledgment somewhere, besides the comment I added above the function?
compat/win32/pthread.c | 22 ++++++++++++++++++++++ compat/win32/pthread.h | 5 +++++ thread-utils.c | 11 +++++++++++ thread-utils.h | 6 ++++++ 4 files changed, 44 insertions(+)
diff --git a/compat/win32/pthread.c b/compat/win32/pthread.c index 2e7eead42c..5a7ecbd999 100644 --- a/compat/win32/pthread.c +++ b/compat/win32/pthread.c @@ -56,3 +56,25 @@ pthread_t pthread_self(void) t.tid = GetCurrentThreadId(); return t; } + +/* Adapted from libav's compat/w32pthreads.h. */ +int pthread_once(pthread_once_t *once_control, void (*init_routine)(void)) +{ + BOOL pending = FALSE; + int ret = 0; + + if(!InitOnceBeginInitialize(once_control, 0, &pending, NULL)) { + ret = err_win_to_posix(GetLastError()); + goto out; + } + + if (pending) + init_routine(); + + if(!InitOnceComplete(once_control, 0, NULL)) + ret = err_win_to_posix(GetLastError()); + +out: + /* POSIX doesn't allow pthread_once() to return EINTR */ + return ret == EINTR ? EIO : ret; +} diff --git a/compat/win32/pthread.h b/compat/win32/pthread.h index 737983d00b..c50f1e89c7 100644 --- a/compat/win32/pthread.h +++ b/compat/win32/pthread.h @@ -40,6 +40,11 @@ typedef int pthread_mutexattr_t; #define pthread_cond_signal WakeConditionVariable #define pthread_cond_broadcast WakeAllConditionVariable +#define pthread_once_t INIT_ONCE + +#define PTHREAD_ONCE_INIT INIT_ONCE_STATIC_INIT +int pthread_once(pthread_once_t *once_control, void (*init_routine)(void)); + /* * Simple thread creation implementation using pthread API */ diff --git a/thread-utils.c b/thread-utils.c index 5329845691..937deb3f2e 100644 --- a/thread-utils.c +++ b/thread-utils.c @@ -122,4 +122,15 @@ int dummy_pthread_join(pthread_t pthread, void **retval) return ENOSYS; } +int nothreads_pthread_once(pthread_once_t *once_control, + void (*init_routine)(void)) +{ + if (*once_control == 1) + return 0; + + init_routine(); + *once_control = 1; + return 0; +} + #endif diff --git a/thread-utils.h b/thread-utils.h index 4961487ed9..bab9dc5e4d 100644 --- a/thread-utils.h +++ b/thread-utils.h @@ -19,6 +19,7 @@ #define pthread_mutex_t int #define pthread_cond_t int #define pthread_key_t int +#define pthread_once_t int #define pthread_mutex_init(mutex, attr) dummy_pthread_init(mutex) #define pthread_mutex_lock(mutex) @@ -48,6 +49,11 @@ int dummy_pthread_join(pthread_t pthread, void **retval); int dummy_pthread_init(void *); +#define PTHREAD_ONCE_INIT 0 +int nothreads_pthread_once(pthread_once_t *once_control, + void (*init_routine)(void)); +#define pthread_once(once, routine) nothreads_pthread_once(once, routine) + #endif int online_cpus(void);
-- 2.26.2