summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorrpj <rpj>1998-07-31 02:10:03 +0000
committerrpj <rpj>1998-07-31 02:10:03 +0000
commit0bc99fb6243a64c6f9a4d503382e9125adeb85a0 (patch)
tree5d0899fe95d32928070aa10dffccbf0b8da09dd5
parent46dc6c8f550e64ed07650b98ea437fdbb1de54c7 (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--ChangeLog8
-rw-r--r--cleanup.c67
-rw-r--r--implement.h5
3 files changed, 80 insertions, 0 deletions
diff --git a/ChangeLog b/ChangeLog
index 909442f..5e97b1c 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -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
diff --git a/cleanup.c b/cleanup.c
index 87aad78..d869ee3 100644
--- a/cleanup.c
+++ b/cleanup.c
@@ -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);