diff options
author | rpj <rpj> | 1998-07-31 02:10:03 +0000 |
---|---|---|
committer | rpj <rpj> | 1998-07-31 02:10:03 +0000 |
commit | 0bc99fb6243a64c6f9a4d503382e9125adeb85a0 (patch) | |
tree | 5d0899fe95d32928070aa10dffccbf0b8da09dd5 | |
parent | 46dc6c8f550e64ed07650b98ea437fdbb1de54c7 (diff) |
Fri Jul 31 00:05:45 1998 Ross Johnson <rpj@ixobrychus.canberra.edu.au>
* implement.h (_pthread_handler_pop_all): Add prototype.
(_pthread_destructor_pop_all): Ditto.
* cleanup.c (_pthread_destructor_push): Implement. This is just a
call to _pthread_handler_push().
(_pthread_destructor_pop_all): Implement. This is significantly
different to _pthread_handler_pop_all().
-rw-r--r-- | ChangeLog | 8 | ||||
-rw-r--r-- | cleanup.c | 67 | ||||
-rw-r--r-- | implement.h | 5 |
3 files changed, 80 insertions, 0 deletions
@@ -1,5 +1,13 @@ Fri Jul 31 00:05:45 1998 Ross Johnson <rpj@ixobrychus.canberra.edu.au> + * implement.h (_pthread_handler_pop_all): Add prototype. + (_pthread_destructor_pop_all): Ditto. + + * cleanup.c (_pthread_destructor_push): Implement. This is just a + call to _pthread_handler_push(). + (_pthread_destructor_pop_all): Implement. This is significantly + different to _pthread_handler_pop_all(). + * Makefile (SRCS): Create. Preliminary. * windows.h: Create. Contains Win32 definitions for compile @@ -116,3 +116,70 @@ _pthread_handler_pop_all(int stack, int execute) } } } + +int +_pthread_destructor_push(void (* routine)(void *), pthread_key_t key) +{ + return _pthread_handler_push(_PTHREAD_DESTRUCTOR_STACK, + _PTHREAD_HANDLER_POP_LIFO, + routine, + key); +} + +void +_pthread_destructor_pop_all() +{ + _pthread_handler_node_t ** head; + _pthread_handler_node_t * current; + _pthread_handler_node_t * next; + void (* func)(void *); + void * arg; + int count; + + head = _PTHREAD_STACK(_PTHREAD_DESTRUCTOR_STACK); + + /* Stop destructor execution at a finite time. POSIX allows us + to ignore this if we like, even at the risk of an infinite loop. + */ + for (count = 0; count < _PTHREAD_DESTRUCTOR_ITERATIONS; count++) + { + /* Loop through all destructors for this thread. */ + while (current != NULL) + { + func = current->routine; + + /* Get the key value using the key which is in current->arg. */ + arg = pthread_getspecific(current->arg); + + next = current->next; + + /* If the key value is non-NULL run the destructor, otherwise + unlink it from the list. + */ + if (arg != NULL) + { + if (func != NULL) + { + (void) func(arg); + } + } + else + { + if (current == *head) + { + *head = next; + } + free(current); + } + current = next; + } + } + + /* Free the destructor list even if we still have non-NULL key values. */ + while (*head != NULL) + { + next = (*head)->next; + free(*head); + *head = next; + } +} diff --git a/implement.h b/implement.h index 9e84942..56fa7b3 100644 --- a/implement.h +++ b/implement.h @@ -107,6 +107,11 @@ void _pthread_handler_pop(int stack, void _pthread_handler_pop_all(int stack, int execute); +int _pthread_destructor_push(void (*routine)(void *), + pthread_key_t key); + +void _pthread_destructor_pop_all(); + /* Primitives to manage threads table entries. */ int _pthread_new_thread(pthread_t * thread); |