diff options
| author | rpj <rpj> | 1998-07-21 17:04:38 +0000 | 
|---|---|---|
| committer | rpj <rpj> | 1998-07-21 17:04:38 +0000 | 
| commit | 492c73cf1f1b3e35b394aec991d1201726ec606d (patch) | |
| tree | f7bddcaa8a2f89e567b94b20bde64973bb626fd2 /cleanup.c | |
| parent | e51aa9d5fe177407b0c29903fec27b589ea529da (diff) | |
Wed Jul 22 00:16:22 1998  Ross Johnson  <rpj@ixobrychus.canberra.edu.au>
	* cleanup.c (_pthread_cleanup_push): Implement.
	(_pthread_cleanup_pop): Implement.
	(_pthread_do_cancellation): Implement.
	These are private to the implementation. The real cleanup functions
	are macros. See below.
	* pthread.h (pthread_cleanup_push): Implement as a macro.
	(pthread_cleanup_pop): Implement as a macro.
	Because these are macros which start and end a block, the POSIX scoping
	requirement is observed. See the comment in the file.
	* exit.c (pthread_exit): Refine the code.
	* create.c (pthread_create): Code cleanup.
	* implement.h (RND_SIZEOF): Add RND_SIZEOF(T) to round sizeof(T)
	up to multiple of DWORD.
	Add function prototypes.
	* private.c (_pthread_getthreadindex): "*thread" should have been
	"thread". Detect empty slot fail condition.
Diffstat (limited to 'cleanup.c')
| -rw-r--r-- | cleanup.c | 67 | 
1 files changed, 67 insertions, 0 deletions
| diff --git a/cleanup.c b/cleanup.c new file mode 100644 index 0000000..f670b97 --- /dev/null +++ b/cleanup.c @@ -0,0 +1,67 @@ +/* + * cleanup.c + * + * Description: + * This translation unit implements routines associated cleaning up + * threads. + */ + +#include "pthread.h" +#include "implement.h" + +void +_pthread_cleanup_push(void (*routine)(void *), void *arg) +{ +  _pthread_cleanup_node_t * next; +  int t; + +  t = _pthread_getthreadindex(pthread_self()); + +  next = (_pthread_cleanup_node_t *) malloc(sizeof(_pthread_cleanup_node_t)); +  if (next == NULL) { +    /* FIXME: INTERNAL ERROR */ +  } + +  next->next = _pthread_threads_table[t]->cleanupstack->first; +  next->routine = routine; +  next->arg = arg; +  _pthread_threads_table[t]->cleanupstack->first = next; +} + +void +_pthread_cleanup_pop(int execute) +{ +  _pthread_cleanup_node_t * handler; +  void (* func)(void *); +  void * arg; +  int t; + +  t = _pthread_getthreadindex(pthread_self()); +  handler = _pthread_threads_table[t]->cleanupstack->first; + +  if (handler != NULL) { +    next = handler->next; +    func = handler->routine; +    arg = handler->arg; + +    free(handler); + +    if (execute != 0) +      (void) func(arg); + +    _pthread_threads_table[t]->cleanupstack->first = next; +  } +} + +void +_pthread_do_cancellation(int tindex) +{ +  _pthread_cleanup_stack_t * stack; + +  stack = _pthread_threads_table[tindex]->cleanupstack; + +  /* Run all the cleanup handlers */ +  while (stack->first != NULL) { +    _pthread_cleanup_pop(1); +  } +} | 
