aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/libthr/thread/thr_private.h16
1 files changed, 15 insertions, 1 deletions
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 *);