diff options
author | Shaobo Song <shnusongshaobo@gmail.com> | 2024-11-10 12:15:04 +0800 |
---|---|---|
committer | Corinna Vinschen <corinna@vinschen.de> | 2024-11-11 13:36:42 +0100 |
commit | 9dad29c238bfce017f54915b90a1c2c4fcac9529 (patch) | |
tree | cf4f9b3a0d8c5147a2cf50ad37af0dea98a193a1 | |
parent | 38ab2b77e325bf5c9d25cb832f8b80c58ff80299 (diff) | |
download | newlib-9dad29c238bfce017f54915b90a1c2c4fcac9529.zip newlib-9dad29c238bfce017f54915b90a1c2c4fcac9529.tar.gz newlib-9dad29c238bfce017f54915b90a1c2c4fcac9529.tar.bz2 |
Cygwin: pthread: Correct pthread_cleanup macros to avoid potential syntax errors
This commit revises `pthread_cleanup_push` and `pthread_cleanup_pop`
macros to use a `do { ... } while(0)` wrapper, preventing syntax errors
when used in certain contexts. The original code could fail when they
are wrapped within a `do { ... } while(0)`, causing unintended behavior
or compilation issues.
Example of error:
#include <pthread.h>
#define pthread_cleanup_push_wrapper(_fn, _arg) do { \
pthread_cleanup_push(_fn, _arg); \
} while (0)
#define pthread_cleanup_pop_wrapper(_execute) do { \
pthread_cleanup_pop(_execute); \
} while (0)
void cleanup_fn (void *arg) {}
void *thread_func (void *arg)
{
pthread_cleanup_push_wrapper(cleanup_fn, NULL);
pthread_cleanup_pop_wrapper(1);
return NULL;
}
int main (int argc, char **argv) {
pthread_t thread_id;
pthread_create(&thread_id, NULL, thread_func, NULL);
}
This would fail due to unmatched braces in the macro expansion. The new
structure ensures the macro expands correctly in all cases.
Fixes: 007276b30e0a ("* cygwin.din: Add _pthread_cleanup_push and _pthread_cleanup_pop.")
Signed-off-by: Shaobo Song <shnusongshaobo@gmail.com>
-rw-r--r-- | winsup/cygwin/include/pthread.h | 11 |
1 files changed, 7 insertions, 4 deletions
diff --git a/winsup/cygwin/include/pthread.h b/winsup/cygwin/include/pthread.h index 66d367d..cf2fcb0 100644 --- a/winsup/cygwin/include/pthread.h +++ b/winsup/cygwin/include/pthread.h @@ -110,10 +110,13 @@ typedef struct _pthread_cleanup_handler void _pthread_cleanup_push (__pthread_cleanup_handler *handler); void _pthread_cleanup_pop (int execute); -#define pthread_cleanup_push(_fn, _arg) { __pthread_cleanup_handler __cleanup_handler = \ - { _fn, _arg, NULL }; \ - _pthread_cleanup_push( &__cleanup_handler ); -#define pthread_cleanup_pop(_execute) _pthread_cleanup_pop( _execute ); } +#define pthread_cleanup_push(_fn, _arg) \ + do { \ + __pthread_cleanup_handler __cleanup_handler = { _fn, _arg, NULL }; \ + _pthread_cleanup_push(&__cleanup_handler) +#define pthread_cleanup_pop(_execute) \ + _pthread_cleanup_pop(_execute); \ + } while (0) /* Condition variables */ int pthread_cond_broadcast (pthread_cond_t *); |