From a032a6587011cbdac8c2f7e11f15dc4e592bbb55 Mon Sep 17 00:00:00 2001 From: Austin Foxley Date: Tue, 16 Feb 2010 12:27:18 -0800 Subject: mass sync with glibc nptl Signed-off-by: Austin Foxley --- libpthread/nptl/sysdeps/unix/sysv/linux/fork.c | 23 ++++++++++++++++------- 1 file changed, 16 insertions(+), 7 deletions(-) (limited to 'libpthread/nptl/sysdeps/unix/sysv/linux/fork.c') diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/fork.c b/libpthread/nptl/sysdeps/unix/sysv/linux/fork.c index a84b5c237..2d4cae224 100644 --- a/libpthread/nptl/sysdeps/unix/sysv/linux/fork.c +++ b/libpthread/nptl/sysdeps/unix/sysv/linux/fork.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2002, 2003 Free Software Foundation, Inc. +/* Copyright (C) 2002, 2003, 2007, 2008 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Ulrich Drepper , 2002. @@ -58,8 +58,9 @@ fresetlockfiles (void) #endif } -extern __typeof(fork) __libc_fork; -pid_t __libc_fork (void) + +pid_t +__libc_fork (void) { pid_t pid; struct used_handler @@ -73,6 +74,9 @@ pid_t __libc_fork (void) struct fork_handler *runp; while ((runp = __fork_handlers) != NULL) { + /* Make sure we read from the current RUNP pointer. */ + atomic_full_barrier (); + unsigned int oldval = runp->refcntr; if (oldval == 0) @@ -166,6 +170,8 @@ pid_t __libc_fork (void) /* Reset locks in the I/O code. */ STDIO_INIT_MUTEX(_stdio_openlist_add_lock); + /* XXX reset any locks in dynamic loader */ + /* Run the handlers registered for the child. */ while (allp != NULL) { @@ -173,8 +179,11 @@ pid_t __libc_fork (void) allp->handler->child_handler (); /* Note that we do not have to wake any possible waiter. - This is the only thread in the new process. */ - --allp->handler->refcntr; + This is the only thread in the new process. The count + may have been bumped up by other threads doing a fork. + We reset it to 1, to avoid waiting for non-existing + thread(s) to release the count. */ + allp->handler->refcntr = 1; /* XXX We could at this point look through the object pool and mark all objects not on the __fork_handlers list as @@ -186,7 +195,7 @@ pid_t __libc_fork (void) } /* Initialize the fork lock. */ - __fork_lock = (lll_lock_t) LLL_LOCK_INITIALIZER; + __fork_lock = LLL_LOCK_INITIALIZER; } else { @@ -206,7 +215,7 @@ pid_t __libc_fork (void) if (atomic_decrement_and_test (&allp->handler->refcntr) && allp->handler->need_signal) - lll_futex_wake (allp->handler->refcntr, 1); + lll_futex_wake (allp->handler->refcntr, 1, LLL_PRIVATE); allp = allp->next; } -- cgit v1.2.3