diff options
author | Ulrich Drepper <drepper@redhat.com> | 2002-12-31 08:00:19 +0000 |
---|---|---|
committer | Ulrich Drepper <drepper@redhat.com> | 2002-12-31 08:00:19 +0000 |
commit | 416d2de60b8e567ac7cd6a581afba0f5cdfc932e (patch) | |
tree | abd37640e253dae0e65751ea12f20253830bb269 /linuxthreads/ptfork.c | |
parent | 89d6e4445954aee95d02b84db7af7fa0cca93195 (diff) | |
download | glibc-416d2de60b8e567ac7cd6a581afba0f5cdfc932e.tar.gz glibc-416d2de60b8e567ac7cd6a581afba0f5cdfc932e.tar.xz glibc-416d2de60b8e567ac7cd6a581afba0f5cdfc932e.zip |
Update.
2002-12-30 Ulrich Drepper <drepper@redhat.com> * malloc/thread-m.h (thread_atfork): Define using __register_atfork.
Diffstat (limited to 'linuxthreads/ptfork.c')
-rw-r--r-- | linuxthreads/ptfork.c | 99 |
1 files changed, 37 insertions, 62 deletions
diff --git a/linuxthreads/ptfork.c b/linuxthreads/ptfork.c index 564f8d7c75..195ffcd1b0 100644 --- a/linuxthreads/ptfork.c +++ b/linuxthreads/ptfork.c @@ -21,96 +21,71 @@ #include "pthread.h" #include "internals.h" #include <bits/libc-lock.h> +#include "fork.h" -struct handler_list { - void (*handler)(void); - struct handler_list * next; -}; +extern int __libc_fork (void); -static pthread_mutex_t pthread_atfork_lock = PTHREAD_MUTEX_INITIALIZER; -static struct handler_list * pthread_atfork_prepare = NULL; -static struct handler_list * pthread_atfork_parent = NULL; -static struct handler_list * pthread_atfork_child = NULL; - -static void pthread_insert_list(struct handler_list ** list, - void (*handler)(void), - struct handler_list * newlist, - int at_end) -{ - if (handler == NULL) return; - if (at_end) { - while(*list != NULL) list = &((*list)->next); - } - newlist->handler = handler; - newlist->next = *list; - *list = newlist; -} - -struct handler_list_block { - struct handler_list prepare, parent, child; -}; - -int __pthread_atfork(void (*prepare)(void), - void (*parent)(void), - void (*child)(void)) -{ - struct handler_list_block * block = - (struct handler_list_block *) malloc(sizeof(struct handler_list_block)); - if (block == NULL) return ENOMEM; - pthread_mutex_lock(&pthread_atfork_lock); - /* "prepare" handlers are called in LIFO */ - pthread_insert_list(&pthread_atfork_prepare, prepare, &block->prepare, 0); - /* "parent" handlers are called in FIFO */ - pthread_insert_list(&pthread_atfork_parent, parent, &block->parent, 1); - /* "child" handlers are called in FIFO */ - pthread_insert_list(&pthread_atfork_child, child, &block->child, 1); - pthread_mutex_unlock(&pthread_atfork_lock); - return 0; -} -strong_alias (__pthread_atfork, pthread_atfork) - -static inline void pthread_call_handlers(struct handler_list * list) -{ - for (/*nothing*/; list != NULL; list = list->next) (list->handler)(); -} - -extern int __libc_fork(void); - -pid_t __fork(void) +pid_t __pthread_fork (struct fork_block *b) { pid_t pid; + list_t *runp; + + __libc_lock_lock (b->lock); - pthread_mutex_lock(&pthread_atfork_lock); + /* Run all the registered preparation handlers. In reverse order. */ + list_for_each_prev (runp, &b->prepare_list) + { + struct fork_handler *curp; + curp = list_entry (runp, struct fork_handler, list); + curp->handler (); + } - pthread_call_handlers(pthread_atfork_prepare); __pthread_once_fork_prepare(); __flockfilelist(); - pid = __libc_fork(); + pid = ARCH_FORK (); if (pid == 0) { __pthread_reset_main_thread(); __fresetlockfiles(); __pthread_once_fork_child(); - pthread_call_handlers(pthread_atfork_child); - pthread_mutex_init(&pthread_atfork_lock, NULL); + /* Run the handlers registered for the child. */ + list_for_each (runp, &b->child_list) + { + struct fork_handler *curp; + curp = list_entry (runp, struct fork_handler, list); + curp->handler (); + } + + __libc_lock_init (b->lock); } else { __funlockfilelist(); __pthread_once_fork_parent(); - pthread_call_handlers(pthread_atfork_parent); - pthread_mutex_unlock(&pthread_atfork_lock); + /* Run the handlers registered for the parent. */ + list_for_each (runp, &b->parent_list) + { + struct fork_handler *curp; + curp = list_entry (runp, struct fork_handler, list); + curp->handler (); + } + + __libc_lock_unlock (b->lock); } return pid; } +pid_t __fork (void) +{ + return __libc_fork (); +} weak_alias (__fork, fork); pid_t __vfork(void) { - return __fork(); + return __libc_fork (); } weak_alias (__vfork, vfork); |