diff options
author | Theo Buehler <tb@openbsd.org> | 2023-12-12 23:20:44 +0100 |
---|---|---|
committer | Brent Cook <busterb@gmail.com> | 2024-03-03 15:32:50 -0600 |
commit | e2827e054a6d4ede3e1287402a1872cca29559fc (patch) | |
tree | e9274bceae469f436766592d9203d3efd2328865 /include/compat | |
parent | a31f8a95b395581ade4d9d71c9b90179d5bfa874 (diff) | |
download | portable-e2827e054a6d4ede3e1287402a1872cca29559fc.tar.gz portable-e2827e054a6d4ede3e1287402a1872cca29559fc.tar.bz2 portable-e2827e054a6d4ede3e1287402a1872cca29559fc.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/compat')
-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 |