summaryrefslogtreecommitdiff
path: root/cleanup.c
diff options
context:
space:
mode:
authorrpj <rpj>1998-07-21 17:04:38 +0000
committerrpj <rpj>1998-07-21 17:04:38 +0000
commit492c73cf1f1b3e35b394aec991d1201726ec606d (patch)
treef7bddcaa8a2f89e567b94b20bde64973bb626fd2 /cleanup.c
parente51aa9d5fe177407b0c29903fec27b589ea529da (diff)
Wed Jul 22 00:16:22 1998 Ross Johnson <rpj@ixobrychus.canberra.edu.au>
* cleanup.c (_pthread_cleanup_push): Implement. (_pthread_cleanup_pop): Implement. (_pthread_do_cancellation): Implement. These are private to the implementation. The real cleanup functions are macros. See below. * pthread.h (pthread_cleanup_push): Implement as a macro. (pthread_cleanup_pop): Implement as a macro. Because these are macros which start and end a block, the POSIX scoping requirement is observed. See the comment in the file. * exit.c (pthread_exit): Refine the code. * create.c (pthread_create): Code cleanup. * implement.h (RND_SIZEOF): Add RND_SIZEOF(T) to round sizeof(T) up to multiple of DWORD. Add function prototypes. * private.c (_pthread_getthreadindex): "*thread" should have been "thread". Detect empty slot fail condition.
Diffstat (limited to 'cleanup.c')
-rw-r--r--cleanup.c67
1 files changed, 67 insertions, 0 deletions
diff --git a/cleanup.c b/cleanup.c
new file mode 100644
index 0000000..f670b97
--- /dev/null
+++ b/cleanup.c
@@ -0,0 +1,67 @@
+/*
+ * cleanup.c
+ *
+ * Description:
+ * This translation unit implements routines associated cleaning up
+ * threads.
+ */
+
+#include "pthread.h"
+#include "implement.h"
+
+void
+_pthread_cleanup_push(void (*routine)(void *), void *arg)
+{
+ _pthread_cleanup_node_t * next;
+ int t;
+
+ t = _pthread_getthreadindex(pthread_self());
+
+ next = (_pthread_cleanup_node_t *) malloc(sizeof(_pthread_cleanup_node_t));
+ if (next == NULL) {
+ /* FIXME: INTERNAL ERROR */
+ }
+
+ next->next = _pthread_threads_table[t]->cleanupstack->first;
+ next->routine = routine;
+ next->arg = arg;
+ _pthread_threads_table[t]->cleanupstack->first = next;
+}
+
+void
+_pthread_cleanup_pop(int execute)
+{
+ _pthread_cleanup_node_t * handler;
+ void (* func)(void *);
+ void * arg;
+ int t;
+
+ t = _pthread_getthreadindex(pthread_self());
+ handler = _pthread_threads_table[t]->cleanupstack->first;
+
+ if (handler != NULL) {
+ next = handler->next;
+ func = handler->routine;
+ arg = handler->arg;
+
+ free(handler);
+
+ if (execute != 0)
+ (void) func(arg);
+
+ _pthread_threads_table[t]->cleanupstack->first = next;
+ }
+}
+
+void
+_pthread_do_cancellation(int tindex)
+{
+ _pthread_cleanup_stack_t * stack;
+
+ stack = _pthread_threads_table[tindex]->cleanupstack;
+
+ /* Run all the cleanup handlers */
+ while (stack->first != NULL) {
+ _pthread_cleanup_pop(1);
+ }
+}