diff options
author | rpj <rpj> | 1998-10-14 03:06:39 +0000 |
---|---|---|
committer | rpj <rpj> | 1998-10-14 03:06:39 +0000 |
commit | 4ed54ca07b8115bd9e7813a1484d4c7936a25e70 (patch) | |
tree | dce1f613f881a7fa06b692ea316922473e3d3690 /cleanup.c | |
parent | 7522a5a3b4f87f79534ae134a087d80e3e4bfa8a (diff) |
Mon Oct 12 00:00:44 1998 Ross Johnson <rpj@ixobrychus.canberra.edu.au>
* implement.h (_pthread_tsd_key_table): New.
* create.c (_pthread_start_call): Initialise per-thread TSD keys
to NULL.
* misc.c (pthread_once): Correct typo in comment.
* implement.h (_pthread_destructor_push): Remove.
(_pthread_destructor_pop): Remove.
(_pthread_destructor_run_all): Rename from _pthread_destructor_pop_all.
(_PTHREAD_TSD_KEY_DELETED): Add enum.
(_PTHREAD_TSD_KEY_INUSE): Add enum.
* cleanup.c (_pthread_destructor_push): Remove.
(_pthread_destructor_pop): Remove.
(_pthread_destructor_run_all): Totally revamped TSD.
* dll.c (_pthread_TSD_keys_TlsIndex): Initialise.
* tsd.c (pthread_setspecific): Totally revamped TSD.
(pthread_getspecific): Ditto.
(pthread_create): Ditto.
(pthread_delete): Ditto.
Sun Oct 11 22:44:55 1998 Ross Johnson <rpj@ixobrychus.canberra.edu.au>
* global.c (_pthread_tsd_key_table): Add new global.
* implement.h (_pthread_tsd_key_t and struct _pthread_tsd_key):
Add.
(struct _pthread): Remove destructorstack.
* cleanup.c (_pthread_destructor_run_all): Rename from
_pthread_destructor_pop_all. The key destructor stack was made
global rather than per-thread. No longer removes destructor nodes
from the stack. Comments updated.
Diffstat (limited to 'cleanup.c')
-rw-r--r-- | cleanup.c | 102 |
1 files changed, 13 insertions, 89 deletions
@@ -120,112 +120,36 @@ _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, - (void *) key); -} - - -/* Remove all of the destructors associated with the key. */ -void -_pthread_destructor_pop(pthread_key_t key) -{ - _pthread_handler_node_t ** head; - _pthread_handler_node_t * current; - _pthread_handler_node_t * next; - - head = _PTHREAD_STACK(_PTHREAD_DESTRUCTOR_STACK); - current = *head; - - while (current != NULL) - { - next = current->next; - - /* The destructors associated key is in current->arg. */ - if (current->arg == (void *) key) - { - if (current == *head) - { - *head = next; - } - free(current); - } - current = next; - } -} - - -/* Run destructors for all non-NULL key values. - - FIXME: Currently we only run the destructors on the calling - thread's key values. The way I interpret POSIX semantics is that, - for each key that the calling thread has a destructor for, we need - to look at the key values of every thread and run the destructor on - it if the key value is non-NULL. - - The question is: how do we access the key associated values which - are private to other threads? - +/* Run destructors for all non-NULL key values for the calling thread. */ void -_pthread_destructor_pop_all() +_pthread_destructor_run_all() { - _pthread_handler_node_t ** head; - _pthread_handler_node_t * current; - _pthread_handler_node_t * next; - void (* func)(void *); + _pthread_tsd_key_t * k; void * arg; int count; - head = _PTHREAD_STACK(_PTHREAD_DESTRUCTOR_STACK); + k = _pthread_tsd_key_table; /* 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) + /* Loop through all keys. */ + for (key = 0; key < _POSIX_THREAD_KEYS_MAX; key++) { - func = current->routine; - - /* Get the key value using the key which is in current->arg. */ - arg = pthread_getspecific((int) current->arg); + if (k->in_use != 1) + continue; - next = current->next; + arg = pthread_getspecific(key); - /* 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 (arg != NULL && k->destructor != NULL) { - if (current == *head) - { - *head = next; - } - free(current); + (void) (k->destructor)(arg); } - 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; + k++; + } } } |