aboutsummaryrefslogtreecommitdiff
path: root/sysdeps/mach/hurd/fork.c
diff options
context:
space:
mode:
Diffstat (limited to 'sysdeps/mach/hurd/fork.c')
-rw-r--r--sysdeps/mach/hurd/fork.c13
1 files changed, 13 insertions, 0 deletions
diff --git a/sysdeps/mach/hurd/fork.c b/sysdeps/mach/hurd/fork.c
index ad09fd7..2e8b59e 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, ());