diff -ruN valgrind-2.2.0/coregrind/vg_libpthread.c valgrind-2.2.0-fixed/coregrind/vg_libpthread.c --- valgrind-2.2.0/coregrind/vg_libpthread.c 2004-12-19 17:30:53.383502976 +0100 +++ valgrind-2.2.0-fixed/coregrind/vg_libpthread.c 2004-12-19 17:31:23.680897072 +0100 @@ -1830,12 +1830,6 @@ /* Initialiser has completed. */ #define P_ONCE_COMPLETED ((PTHREAD_ONCE_INIT) + 2) -int __pthread_once ( pthread_once_t *once_control, - void (*init_routine) (void) ) -{ - int res; - int done; - # define TAKE_LOCK \ res = __pthread_mutex_lock(&once_masterlock); \ my_assert(res == 0); @@ -1844,11 +1838,19 @@ res = __pthread_mutex_unlock(&once_masterlock); \ my_assert(res == 0); - void cleanup(void *v) { - TAKE_LOCK; - *once_control = P_ONCE_NOT_DONE; - RELEASE_LOCK; - } +static void cleanup(void *once_control) { + int res; + TAKE_LOCK; + *(pthread_once_t *)once_control = P_ONCE_NOT_DONE; + RELEASE_LOCK; +} + +int __pthread_once ( pthread_once_t *once_control, + void (*init_routine) (void) ) +{ + int res; + int done; + ensure_valgrind("pthread_once"); @@ -1863,7 +1865,7 @@ /* Not started. Change state to indicate running, drop the lock and run. */ *once_control = P_ONCE_RUNNING; - _pthread_cleanup_push(NULL, cleanup, NULL); + _pthread_cleanup_push(NULL, cleanup, once_control); RELEASE_LOCK; init_routine(); /* re-take the lock, and set state to indicate done. */ @@ -1904,9 +1906,10 @@ return 0; +} + # undef TAKE_LOCK # undef RELEASE_LOCK -} #undef P_ONCE_NOT_DONE #undef P_ONCE_RUNNING