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.
Signed-off-by: Shaobo Song <[email protected]>
---
winsup/cygwin/include/pthread.h | 11 +++++++----
1 file changed, 7 insertions(+), 4 deletions(-)
diff --git a/winsup/cygwin/include/pthread.h b/winsup/cygwin/include/pthread.h
index 66d367d62..cf2fcb04b 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 *);
--
2.25.1