pthread cleanup macros are broken

Asked by Donny Viszneki

donny@pacemates:~/gpsee/src$ echo -e '#include <pthread.h>\npthread_cleanup_push(foo, bar)' | gcc -Wall -E - | tail -n 1
do { __pthread_unwind_buf_t __cancel_buf; void (*__cancel_routine) (void *) = (foo); void *__cancel_arg = (bar); int not_first_call = __sigsetjmp ((struct __jmp_buf_tag *) (void *) __cancel_buf.__cancel_jmp_buf, 0); if (__builtin_expect (not_first_call, 0)) { __cancel_routine (__cancel_arg); __pthread_unwind_next (&__cancel_buf); } __pthread_register_cancel (&__cancel_buf); do {

Just look at the very end of the output there and you can see how wrong that is. There's no reason the result of that macro should *end* with "do{"!!!

donny@pacemates:~/gpsee/src$ gcc --version
gcc (Ubuntu 4.3.3-5ubuntu4) 4.3.3
Copyright (C) 2008 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

Question information

Language:
English Edit question
Status:
Solved
For:
Ubuntu Edit question
Assignee:
No assignee Edit question
Solved by:
Colin Ian King
Solved:
Last query:
Last reply:
Revision history for this message
Best Colin Ian King (colin-king) said :
#1

pthread_cleanup_push must be used in conjunction with pthread_cleanup_pop(): See the comment in pthread.h:

/* ....
   pthread_cleanup_push and pthread_cleanup_pop are macros and must always
   be used in matching pairs at the same nesting level of braces. */
# define pthread_cleanup_push(routine, arg) \
  do { \
    __pthread_cleanup_class __clframe (routine, arg)

/* Remove a cleanup handler installed by the matching pthread_cleanup_push.
   If EXECUTE is non-zero, the handler function is called. */
# define pthread_cleanup_pop(execute) \
    __clframe.__setdoit (execute); \
  } while (0)

Hope that explains why!

Revision history for this message
Donny Viszneki (donny-viszneki) said :
#2

Oh my.. I should have researched deeper first!

That is actually a pthreads API I have never learned about, I was only using them indirectly in some code that is used in a specialized sort of linker I am helping to hack.

Thanks a lot for your answer!