aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/jemalloc/internal/private_symbols.txt3
-rw-r--r--include/jemalloc/internal/witness.h3
-rw-r--r--src/jemalloc.c6
-rw-r--r--src/witness.c14
-rw-r--r--test/unit/fork.c25
5 files changed, 42 insertions, 9 deletions
diff --git a/include/jemalloc/internal/private_symbols.txt b/include/jemalloc/internal/private_symbols.txt
index 0eb7778..de884fc 100644
--- a/include/jemalloc/internal/private_symbols.txt
+++ b/include/jemalloc/internal/private_symbols.txt
@@ -594,7 +594,8 @@ witness_lock_error
witness_lockless_error
witness_not_owner_error
witness_owner_error
-witness_postfork
+witness_postfork_child
+witness_postfork_parent
witness_prefork
witness_unlock
witnesses_cleanup
diff --git a/include/jemalloc/internal/witness.h b/include/jemalloc/internal/witness.h
index ecdc034..b2e6e82 100644
--- a/include/jemalloc/internal/witness.h
+++ b/include/jemalloc/internal/witness.h
@@ -96,7 +96,8 @@ void witness_assert_lockless(tsd_t *tsd);
void witnesses_cleanup(tsd_t *tsd);
void witness_fork_cleanup(tsd_t *tsd);
void witness_prefork(tsd_t *tsd);
-void witness_postfork(tsd_t *tsd);
+void witness_postfork_parent(tsd_t *tsd);
+void witness_postfork_child(tsd_t *tsd);
#endif /* JEMALLOC_H_EXTERNS */
/******************************************************************************/
diff --git a/src/jemalloc.c b/src/jemalloc.c
index a7acf5f..cd97ea1 100644
--- a/src/jemalloc.c
+++ b/src/jemalloc.c
@@ -2770,8 +2770,8 @@ _malloc_prefork(void)
narenas = narenas_total_get();
- /* Acquire all mutexes in a safe order. */
witness_prefork(tsd);
+ /* Acquire all mutexes in a safe order. */
ctl_prefork(tsd);
malloc_mutex_prefork(tsd, &arenas_lock);
prof_prefork0(tsd);
@@ -2815,6 +2815,7 @@ _malloc_postfork(void)
tsd = tsd_fetch();
+ witness_postfork_parent(tsd);
/* Release all mutexes, now that fork() has completed. */
chunk_postfork_parent(tsd);
base_postfork_parent(tsd);
@@ -2827,7 +2828,6 @@ _malloc_postfork(void)
prof_postfork_parent(tsd);
malloc_mutex_postfork_parent(tsd, &arenas_lock);
ctl_postfork_parent(tsd);
- witness_postfork(tsd);
}
void
@@ -2840,6 +2840,7 @@ jemalloc_postfork_child(void)
tsd = tsd_fetch();
+ witness_postfork_child(tsd);
/* Release all mutexes, now that fork() has completed. */
chunk_postfork_child(tsd);
base_postfork_child(tsd);
@@ -2852,7 +2853,6 @@ jemalloc_postfork_child(void)
prof_postfork_child(tsd);
malloc_mutex_postfork_child(tsd, &arenas_lock);
ctl_postfork_child(tsd);
- witness_postfork(tsd);
}
/******************************************************************************/
diff --git a/src/witness.c b/src/witness.c
index b5384a2..31c36a2 100644
--- a/src/witness.c
+++ b/src/witness.c
@@ -222,8 +222,20 @@ witness_prefork(tsd_t *tsd)
}
void
-witness_postfork(tsd_t *tsd)
+witness_postfork_parent(tsd_t *tsd)
{
tsd_witness_fork_set(tsd, false);
}
+
+void
+witness_postfork_child(tsd_t *tsd)
+{
+#ifndef JEMALLOC_MUTEX_INIT_CB
+ witness_list_t *witnesses;
+
+ witnesses = tsd_witnessesp_get(tsd);
+ ql_new(witnesses);
+#endif
+ tsd_witness_fork_set(tsd, false);
+}
diff --git a/test/unit/fork.c b/test/unit/fork.c
index 890bc86..d64f2e0 100644
--- a/test/unit/fork.c
+++ b/test/unit/fork.c
@@ -11,6 +11,13 @@ TEST_BEGIN(test_fork)
assert_ptr_not_null(p, "Unexpected malloc() failure");
pid = fork();
+
+ free(p);
+
+ p = malloc(64);
+ assert_ptr_not_null(p, "Unexpected malloc() failure");
+ free(p);
+
if (pid == -1) {
/* Error. */
test_fail("Unexpected fork() failure");
@@ -21,11 +28,23 @@ TEST_BEGIN(test_fork)
int status;
/* Parent. */
- free(p);
- do {
+ while (true) {
if (waitpid(pid, &status, 0) == -1)
test_fail("Unexpected waitpid() failure");
- } while (!WIFEXITED(status) && !WIFSIGNALED(status));
+ if (WIFSIGNALED(status)) {
+ test_fail("Unexpected child termination due to "
+ "signal %d", WTERMSIG(status));
+ break;
+ }
+ if (WIFEXITED(status)) {
+ if (WEXITSTATUS(status) != 0) {
+ test_fail(
+ "Unexpected child exit value %d",
+ WEXITSTATUS(status));
+ }
+ break;
+ }
+ }
}
}
TEST_END