From 4ed54ca07b8115bd9e7813a1484d4c7936a25e70 Mon Sep 17 00:00:00 2001 From: rpj Date: Wed, 14 Oct 1998 03:06:39 +0000 Subject: Mon Oct 12 00:00:44 1998 Ross Johnson * 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 * 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. --- cleanup.c | 102 ++++++++------------------------------------------------------ 1 file changed, 13 insertions(+), 89 deletions(-) (limited to 'cleanup.c') diff --git a/cleanup.c b/cleanup.c index 7a7ea4e..c956ce7 100644 --- a/cleanup.c +++ b/cleanup.c @@ -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++; + } } } -- cgit v1.2.3