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 |
