Skip to content

Commit

Permalink
Cygwin: pthread: Correct pthread_cleanup macros to avoid potential sy…
Browse files Browse the repository at this point in the history
…ntax 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: 007276b ("* cygwin.din: Add _pthread_cleanup_push and _pthread_cleanup_pop.")
Signed-off-by: Shaobo Song <[email protected]>
  • Loading branch information
shaobosong authored and github-cygwin committed Nov 11, 2024
1 parent 30d2669 commit 6876520
Showing 1 changed file with 7 additions and 4 deletions.
11 changes: 7 additions & 4 deletions winsup/cygwin/include/pthread.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 *);
Expand Down

0 comments on commit 6876520

Please sign in to comment.