diff --git a/lib/libthr/thread/thr_private.h b/lib/libthr/thread/thr_private.h index 3cc0fe61de00..9ea56b5b8a35 100644 --- a/lib/libthr/thread/thr_private.h +++ b/lib/libthr/thread/thr_private.h @@ -249,7 +249,9 @@ struct pthread_cleanup { }; #define THR_CLEANUP_PUSH(td, func, arg) { \ - struct pthread_cleanup __cup; \ + struct pthread_cleanup __cup \ + __attribute__((__cleanup__( \ + _thr_cleanup_unwind))); \ \ __cup.routine = func; \ __cup.routine_arg = arg; \ @@ -949,6 +951,18 @@ _thr_check_init(void) _libpthread_init(NULL); } +static inline void +_thr_cleanup_unwind(struct pthread_cleanup *cup) +{ + struct pthread *curthread; + + curthread = _get_curthread(); + if (curthread->cleanup == cup) { + curthread->cleanup = cup->prev; + cup->routine(cup->routine_arg); + } +} + struct wake_addr *_thr_alloc_wake_addr(void); void _thr_release_wake_addr(struct wake_addr *); int _thr_sleep(struct pthread *, int, const struct timespec *);