summaryrefslogtreecommitdiff
path: root/cleanup.c
diff options
context:
space:
mode:
authorrpj <rpj>1998-10-14 03:06:39 +0000
committerrpj <rpj>1998-10-14 03:06:39 +0000
commit4ed54ca07b8115bd9e7813a1484d4c7936a25e70 (patch)
treedce1f613f881a7fa06b692ea316922473e3d3690 /cleanup.c
parent7522a5a3b4f87f79534ae134a087d80e3e4bfa8a (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.c102
1 files changed, 13 insertions, 89 deletions
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++;
+ }
}
}