diff -urp src.old/winsup/cygwin/cygwin.din src/winsup/cygwin/cygwin.din --- src.old/winsup/cygwin/cygwin.din Sat Jan 19 18:45:46 2002 +++ src/winsup/cygwin/cygwin.din Tue Apr 23 11:20:51 2002 @@ -1153,6 +1153,8 @@ pthread_attr_setschedpolicy pthread_attr_setscope pthread_attr_setstacksize pthread_cancel +_pthread_cleanup_push +_pthread_cleanup_pop pthread_cond_broadcast pthread_cond_destroy pthread_cond_init diff -urp src.old/winsup/cygwin/include/pthread.h src/winsup/cygwin/include/pthread.h --- src.old/winsup/cygwin/include/pthread.h Thu Nov 22 02:55:41 2001 +++ src/winsup/cygwin/include/pthread.h Wed Apr 24 10:32:37 2002 @@ -103,10 +103,20 @@ void pthread_cleanup_push (void (*routin void pthread_cleanup_pop (int execute); */ typedef void (*__cleanup_routine_type) (void *); +typedef struct _pthread_cleanup_handler +{ + __cleanup_routine_type function; + void *arg; + struct _pthread_cleanup_handler *next; +} __pthread_cleanup_handler; -#define pthread_cleanup_push(fn, arg) { __cleanup_routine_type __cleanup_routine=fn; \ -void *__cleanup_param=arg; -#define pthread_cleanup_pop(execute) if (execute) __cleanup_routine(__cleanup_param); } +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 ); } /* Condition variables */ int pthread_cond_broadcast (pthread_cond_t *); diff -urp src.old/winsup/cygwin/pthread.cc src/winsup/cygwin/pthread.cc --- src.old/winsup/cygwin/pthread.cc Fri Oct 5 07:05:09 2001 +++ src/winsup/cygwin/pthread.cc Wed Apr 24 10:35:36 2002 @@ -445,6 +445,18 @@ pthread_testcancel (void) __pthread_testcancel (); } +void +_pthread_cleanup_push (__pthread_cleanup_handler *handler) +{ + __pthread_cleanup_push (handler); +} + +void +_pthread_cleanup_pop (int execute) +{ + __pthread_cleanup_pop (execute); +} + /* Semaphores */ int sem_init (sem_t * sem, int pshared, unsigned int value) diff -urp src.old/winsup/cygwin/thread.cc src/winsup/cygwin/thread.cc --- src.old/winsup/cygwin/thread.cc Wed Apr 24 10:24:01 2002 +++ src/winsup/cygwin/thread.cc Tue Apr 23 15:42:32 2002 @@ -346,7 +346,7 @@ MTinterface::fixup_after_fork (void) } pthread::pthread ():verifyable_object (PTHREAD_MAGIC), win32_obj_id (0), - cancelstate (0), canceltype (0), joiner(NULL) + cancelstate (0), canceltype (0), cleanup_handlers(NULL), joiner(NULL) { } @@ -1220,6 +1220,42 @@ __pthread_testcancel (void) *does something*/ } +void +__pthread_cleanup_push (__pthread_cleanup_handler *handler) +{ + pthread_t thread = __pthread_self (); + + handler->next = thread->cleanup_handlers; + thread->cleanup_handlers = handler; +} + +void +__pthread_cleanup_pop (int execute) +{ + pthread_t thread = __pthread_self (); + + if( thread->cleanup_handlers != NULL ) + { + __pthread_cleanup_handler *handler = thread->cleanup_handlers; + + if (execute) + (*handler->function) (handler->arg); + + thread->cleanup_handlers = handler->next; + } +} + +void +__pthread_cleanup_pop_all (void) +{ + pthread_t thread = __pthread_self (); + + while(thread->cleanup_handlers != NULL) + { + __pthread_cleanup_pop (1); + } +} + /* *Races in pthread_atfork: *We are race safe in that any additions to the lists are made via @@ -1495,6 +1531,9 @@ void __pthread_exit (void *value_ptr) { pthread_t thread = __pthread_self (); + + // run cleanup handlers + __pthread_cleanup_pop_all (); MT_INTERFACE->destructors.IterateNull (); diff -urp src.old/winsup/cygwin/thread.h src/winsup/cygwin/thread.h --- src.old/winsup/cygwin/thread.h Wed Apr 24 10:14:14 2002 +++ src/winsup/cygwin/thread.h Tue Apr 23 15:42:49 2002 @@ -239,6 +239,7 @@ public: void *return_ptr; bool suspended; int cancelstate, canceltype; + __pthread_cleanup_handler *cleanup_handlers; pthread_t joiner; // int joinable; @@ -503,6 +504,9 @@ int __pthread_cancel (pthread_t thread); int __pthread_setcancelstate (int state, int *oldstate); int __pthread_setcanceltype (int type, int *oldtype); void __pthread_testcancel (void); +void __pthread_cleanup_push (__pthread_cleanup_handler *handler); +void __pthread_cleanup_pop (int execute); +void __pthread_cleanup_pop_all (void); /* Semaphores */