summaryrefslogtreecommitdiff
path: root/cleanup.c
diff options
context:
space:
mode:
authorrpj <rpj>1998-07-22 16:42:53 +0000
committerrpj <rpj>1998-07-22 16:42:53 +0000
commitf33f4460f9de9c2d2ae6f3bf05caed391c6ad485 (patch)
tree12bb86525d369c1c4de220bb58d92d3eab2f5a7e /cleanup.c
parentb84f1cc523f4236200689b2f78b16b26bc05f429 (diff)
Wed Jul 22 00:16:22 1998 Ross Johnson <rpj@ixobrychus.canberra.edu.au>
* 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.
Diffstat (limited to 'cleanup.c')
-rw-r--r--cleanup.c100
1 files changed, 62 insertions, 38 deletions
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);
+ }
}