aboutsummaryrefslogtreecommitdiff
path: root/sysdeps
diff options
context:
space:
mode:
Diffstat (limited to 'sysdeps')
-rw-r--r--sysdeps/mach/hurd/fork.c13
-rw-r--r--sysdeps/nptl/fork.c13
2 files changed, 25 insertions, 1 deletions
diff --git a/sysdeps/mach/hurd/fork.c b/sysdeps/mach/hurd/fork.c
index ad09fd7c41..2e8b59e7c0 100644
--- a/sysdeps/mach/hurd/fork.c
+++ b/sysdeps/mach/hurd/fork.c
@@ -26,6 +26,7 @@
#include <assert.h>
#include "hurdmalloc.h" /* XXX */
#include <tls.h>
+#include <malloc/malloc-internal.h>
#undef __fork
@@ -107,6 +108,12 @@ __fork (void)
/* Run things that prepare for forking before we create the task. */
RUN_HOOK (_hurd_fork_prepare_hook, ());
+ /* Acquire malloc locks. This needs to come last because fork
+ handlers may use malloc, and the libio list lock has an
+ indirect malloc dependency as well (via the getdelim
+ function). */
+ __malloc_fork_lock_parent ();
+
/* Lock things that want to be locked before we fork. */
{
void *const *p;
@@ -604,6 +611,9 @@ __fork (void)
nthreads * sizeof (*threads));
}
+ /* Release malloc locks. */
+ __malloc_fork_unlock_parent ();
+
/* Run things that want to run in the parent to restore it to
normality. Usually prepare hooks and parent hooks are
symmetrical: the prepare hook arrests state in some way for the
@@ -655,6 +665,9 @@ __fork (void)
/* Forking clears the trace flag. */
__sigemptyset (&_hurdsig_traced);
+ /* Release malloc locks. */
+ __malloc_fork_unlock_child ();
+
/* Run things that want to run in the child task to set up. */
RUN_HOOK (_hurd_fork_child_hook, ());
diff --git a/sysdeps/nptl/fork.c b/sysdeps/nptl/fork.c
index 27f8d52e30..1a68cbd647 100644
--- a/sysdeps/nptl/fork.c
+++ b/sysdeps/nptl/fork.c
@@ -31,7 +31,7 @@
#include <fork.h>
#include <arch-fork.h>
#include <futex-internal.h>
-
+#include <malloc/malloc-internal.h>
static void
fresetlockfiles (void)
@@ -111,6 +111,11 @@ __libc_fork (void)
_IO_list_lock ();
+ /* Acquire malloc locks. This needs to come last because fork
+ handlers may use malloc, and the libio list lock has an indirect
+ malloc dependency as well (via the getdelim function). */
+ __malloc_fork_lock_parent ();
+
#ifndef NDEBUG
pid_t ppid = THREAD_GETMEM (THREAD_SELF, tid);
#endif
@@ -168,6 +173,9 @@ __libc_fork (void)
# endif
#endif
+ /* Release malloc locks. */
+ __malloc_fork_unlock_child ();
+
/* Reset the file list. These are recursive mutexes. */
fresetlockfiles ();
@@ -209,6 +217,9 @@ __libc_fork (void)
/* Restore the PID value. */
THREAD_SETMEM (THREAD_SELF, pid, parentpid);
+ /* Release malloc locks, parent process variant. */
+ __malloc_fork_unlock_parent ();
+
/* We execute this even if the 'fork' call failed. */
_IO_list_unlock ();