diff options
author | Ted Unangst <tedu@cvs.openbsd.org> | 2005-12-14 06:07:55 +0000 |
---|---|---|
committer | Ted Unangst <tedu@cvs.openbsd.org> | 2005-12-14 06:07:55 +0000 |
commit | 32eefeb935d95a67efef35682775d19eacb04ae6 (patch) | |
tree | 2330d85b954a8e5062e1a65cb3ddd0864fc2d5d8 /lib/librthread/rthread.c | |
parent | 6ae4e33cbd86dce56e7209b706f25a96c5cc827c (diff) |
add pthread_cleanup_push and pthread_cleanup_pop
Diffstat (limited to 'lib/librthread/rthread.c')
-rw-r--r-- | lib/librthread/rthread.c | 40 |
1 files changed, 39 insertions, 1 deletions
diff --git a/lib/librthread/rthread.c b/lib/librthread/rthread.c index 6ec7af49af0..c1916bc0937 100644 --- a/lib/librthread/rthread.c +++ b/lib/librthread/rthread.c @@ -1,4 +1,4 @@ -/* $OpenBSD: rthread.c,v 1.6 2005/12/14 05:44:49 tedu Exp $ */ +/* $OpenBSD: rthread.c,v 1.7 2005/12/14 06:07:54 tedu Exp $ */ /* * Copyright (c) 2004 Ted Unangst <tedu@openbsd.org> * All Rights Reserved. @@ -141,12 +141,19 @@ pthread_self(void) void pthread_exit(void *retval) { + struct rthread_cleanup_fn *clfn; pthread_t thread = pthread_self(); thread->retval = retval; thread->flags |= THREAD_DONE; _sem_post(&thread->donesem); + for (clfn = thread->cleanup_fns; clfn; ) { + struct rthread_cleanup_fn *oclfn = clfn; + clfn = clfn->next; + oclfn->fn(oclfn->arg); + free(oclfn); + } rthread_tls_destructors(thread); #if 0 if (thread->flags & THREAD_DETACHED) @@ -286,6 +293,37 @@ pthread_setcanceltype(int type, int *oldtypep) return (0); } +void +pthread_cleanup_push(void (*fn)(void *), void *arg) +{ + struct rthread_cleanup_fn *clfn; + pthread_t self = pthread_self(); + + clfn = malloc(sizeof(*clfn)); + if (!clfn) + return; + memset(clfn, 0, sizeof(*clfn)); + clfn->fn = fn; + clfn->arg = arg; + clfn->next = self->cleanup_fns; + self->cleanup_fns = clfn; +} + +void +pthread_cleanup_pop(int execute) +{ + struct rthread_cleanup_fn *clfn; + pthread_t self = pthread_self(); + + clfn = self->cleanup_fns; + if (clfn) { + self->cleanup_fns = clfn->next; + if (execute) + clfn->fn(clfn->arg); + free(clfn); + } +} + /* * _np functions */ |