diff options
author | Theo Buehler <tb@openbsd.org> | 2023-12-12 23:20:44 +0100 |
---|---|---|
committer | Theo Buehler <tb@openbsd.org> | 2023-12-12 23:25:06 +0100 |
commit | 0491aef86c41e9d1de19a64e1780ff82d35ccf54 (patch) | |
tree | 995f6c473e1807bbc14eabe0c1fa0399b4300327 /include | |
parent | 223bc4e01e283db48693f631852a0f83ea232308 (diff) | |
download | portable-0491aef86c41e9d1de19a64e1780ff82d35ccf54.tar.gz portable-0491aef86c41e9d1de19a64e1780ff82d35ccf54.tar.bz2 portable-0491aef86c41e9d1de19a64e1780ff82d35ccf54.zip |
pthreads.h: avoid undefined behavior
You can't pass a function pointer through a void pointer.
So wrap the pthread callback in a struct.
Fixes #966
Diffstat (limited to 'include')
-rw-r--r-- | include/compat/pthread.h | 11 |
1 files changed, 8 insertions, 3 deletions
diff --git a/include/compat/pthread.h b/include/compat/pthread.h index 1ab011c..ed1b9dc 100644 --- a/include/compat/pthread.h +++ b/include/compat/pthread.h | |||
@@ -30,18 +30,23 @@ struct pthread_once { | |||
30 | }; | 30 | }; |
31 | typedef struct pthread_once pthread_once_t; | 31 | typedef struct pthread_once pthread_once_t; |
32 | 32 | ||
33 | struct _pthread_win32_cb_arg { | ||
34 | void (*cb)(void); | ||
35 | }; | ||
36 | |||
33 | static inline BOOL CALLBACK | 37 | static inline BOOL CALLBACK |
34 | _pthread_once_win32_cb(PINIT_ONCE once, PVOID param, PVOID *context) | 38 | _pthread_once_win32_cb(PINIT_ONCE once, PVOID param, PVOID *context) |
35 | { | 39 | { |
36 | void (*cb) (void) = param; | 40 | struct _pthread_win32_cb_arg *arg = param; |
37 | cb(); | 41 | arg->cb(); |
38 | return TRUE; | 42 | return TRUE; |
39 | } | 43 | } |
40 | 44 | ||
41 | static inline int | 45 | static inline int |
42 | pthread_once(pthread_once_t *once, void (*cb) (void)) | 46 | pthread_once(pthread_once_t *once, void (*cb) (void)) |
43 | { | 47 | { |
44 | BOOL rc = InitOnceExecuteOnce(&once->once, _pthread_once_win32_cb, cb, NULL); | 48 | struct _pthread_win32_cb_arg arg = { .cb = cb }; |
49 | BOOL rc = InitOnceExecuteOnce(&once->once, _pthread_once_win32_cb, &arg, NULL); | ||
45 | if (rc == 0) | 50 | if (rc == 0) |
46 | return -1; | 51 | return -1; |
47 | else | 52 | else |