From f33f4460f9de9c2d2ae6f3bf05caed391c6ad485 Mon Sep 17 00:00:00 2001 From: rpj Date: Wed, 22 Jul 1998 16:42:53 +0000 Subject: Wed Jul 22 00:16:22 1998 Ross Johnson * attr.c, implement.h, pthread.h, ChangeLog: Resolve CVS merge conflicts. * private.c (_pthread_find_thread_entry): Changes to return type to support leaner _pthread_threads_table[] which now only stores _pthread_thread_thread_t *. (_pthread_new_thread_entry): Internal changes. (_pthread_delete_thread_entry): Internal changes to avoid contention. Calling routines changed accordingly. * pthread.h: Modified cleanup macros to use new generic push and pop. Added destructor and atfork stacks to _pthread_threads_thread_t. * cleanup.c (_pthread_handler_push, _pthread_handler_pop, _pthread_handler_pop_all): Renamed cleanup push and pop routines and made generic to handle destructors and atfork handlers as well. * create.c (_pthread_start_call): New function is a wrapper for all new threads. It allows us to do some cleanup when the thread returns, ie. that is otherwise only done if the thread is cancelled. * exit.c (_pthread_vacuum): New function contains code from pthread_exit() that we need in the new _pthread_start_call() as well. * implement.h: Various additions and minor changes. * pthread.h: Various additions and minor changes. Change cleanup handler macros to use generic handler push and pop functions. * attr.c: Minor mods to all functions. (is_attr): Implemented missing function. * create.c (pthread_create): More clean up. * private.c (_pthread_find_thread_entry): Implement. (_pthread_delete_thread_entry): Implement. (_pthread_new_thread_entry): Implement. These functions manipulate the implementations internal thread table and are part of general code cleanup and modularisation. They replace _pthread_getthreadindex() which was removed. * exit.c (pthread_exit): Changed to use the new code above. * pthread.h: Add cancelability constants. Update comments. --- cleanup.c | 100 ++++++++++++++++++++++++++++++++++++++------------------------ 1 file changed, 62 insertions(+), 38 deletions(-) (limited to 'cleanup.c') diff --git a/cleanup.c b/cleanup.c index f670b97..9ea4316 100644 --- a/cleanup.c +++ b/cleanup.c @@ -10,58 +10,82 @@ #include "implement.h" void -_pthread_cleanup_push(void (*routine)(void *), void *arg) +_pthread_handler_push(_pthread_handler_node_t ** stacktop, + int poporder, + void (*routine)(void *), + void *arg) { - _pthread_cleanup_node_t * next; - int t; + /* Place the new handler into the list so that handlers are + popped off in the order given by poporder. */ + _pthread_handler_node_t * new; + _pthread_handler_node_t * next; - t = _pthread_getthreadindex(pthread_self()); + new = (_pthread_handler_node_t *) malloc(sizeof(_pthread_handler_node_t)); - next = (_pthread_cleanup_node_t *) malloc(sizeof(_pthread_cleanup_node_t)); - if (next == NULL) { - /* FIXME: INTERNAL ERROR */ - } + if (new == 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; + new->routine = routine; + new->arg = arg; + + if (poporder == _PTHREAD_HANDLER_POP_LIFO) + { + /* Add the new node to the start of the list. */ + new->next = *stacktop; + stacktop = next; + } + else + { + /* Add the new node to the end of the list. */ + new->next = NULL; + + if (*stacktop == NULL) + { + *stacktop = new; + } + else + { + next = *stacktop; + while (next != NULL) + { + next = next->next; + } + next = new; + } + } } void -_pthread_cleanup_pop(int execute) +_pthread_handler_pop(_pthread_handler_node_t ** stacktop, + 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; + _pthread_handler_node_t * handler = *stacktop; - if (handler != NULL) { - next = handler->next; - func = handler->routine; - arg = handler->arg; + if (handler != NULL) + { + void (* func)(void *) = handler->routine; + void * arg = handler->arg; - free(handler); + *stacktop = handler->next; - if (execute != 0) - (void) func(arg); + free(handler); - _pthread_threads_table[t]->cleanupstack->first = next; - } + if (execute != 0 && func != NULL) + { + (void) func(arg); + } + } } void -_pthread_do_cancellation(int tindex) +_pthread_handler_pop_all(_pthread_handler_node_t ** stacktop, + int execute) { - _pthread_cleanup_stack_t * stack; - - stack = _pthread_threads_table[tindex]->cleanupstack; - - /* Run all the cleanup handlers */ - while (stack->first != NULL) { - _pthread_cleanup_pop(1); - } + /* Pop and run all handlers on the given stack. */ + while (*stacktop != NULL) + { + _pthread_handler_pop(stacktop, execute); + } } -- cgit v1.2.3