From 492c73cf1f1b3e35b394aec991d1201726ec606d Mon Sep 17 00:00:00 2001 From: rpj Date: Tue, 21 Jul 1998 17:04:38 +0000 Subject: Wed Jul 22 00:16:22 1998 Ross Johnson * 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. --- cleanup.c | 67 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 67 insertions(+) create mode 100644 cleanup.c (limited to 'cleanup.c') 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); + } +} -- cgit v1.2.3