@@ -85,6 +85,7 @@ JEMALLOC_ATTR(weak_import);
85
85
static malloc_zone_t * default_zone , * purgeable_zone ;
86
86
static malloc_zone_t jemalloc_zone ;
87
87
static struct malloc_introspection_t jemalloc_zone_introspect ;
88
+ static pid_t zone_force_lock_pid = -1 ;
88
89
89
90
/******************************************************************************/
90
91
/* Function prototypes for non-inline static functions. */
@@ -288,24 +289,42 @@ zone_log(malloc_zone_t *zone, void *address)
288
289
static void
289
290
zone_force_lock (malloc_zone_t * zone )
290
291
{
291
-
292
- if (isthreaded )
292
+ if (isthreaded ) {
293
+ /*
294
+ * See the note in zone_force_unlock, below, to see why we need
295
+ * this.
296
+ */
297
+ assert (zone_force_lock_pid == -1 );
298
+ zone_force_lock_pid = getpid ();
293
299
jemalloc_prefork ();
300
+ }
294
301
}
295
302
296
303
static void
297
304
zone_force_unlock (malloc_zone_t * zone )
298
305
{
299
306
300
307
/*
301
- * Call jemalloc_postfork_child() rather than
302
- * jemalloc_postfork_parent(), because this function is executed by both
303
- * parent and child. The parent can tolerate having state
304
- * reinitialized, but the child cannot unlock mutexes that were locked
305
- * by the parent.
308
+ * zone_force_lock and zone_force_unlock are the entry points to the
309
+ * forking machinery on OS X. The tricky thing is, the child is not
310
+ * allowed to unlock mutexes locked in the parent, even if owned by the
311
+ * forking thread (and the mutex type we use in OS X will fail an assert
312
+ * if we try). In the child, we can get away with reinitializing all
313
+ * the mutexes, which has the effect of unlocking them. In the parent,
314
+ * doing this would mean we wouldn't wake any waiters blocked on the
315
+ * mutexes we unlock. So, we record the pid of the current thread in
316
+ * zone_force_lock, and use that to detect if we're in the parent or
317
+ * child here, to decide which unlock logic we need.
306
318
*/
307
- if (isthreaded )
308
- jemalloc_postfork_child ();
319
+ if (isthreaded ) {
320
+ assert (zone_force_lock_pid != -1 );
321
+ if (getpid () == zone_force_lock_pid ) {
322
+ jemalloc_postfork_parent ();
323
+ } else {
324
+ jemalloc_postfork_child ();
325
+ }
326
+ zone_force_lock_pid = -1 ;
327
+ }
309
328
}
310
329
311
330
static void
0 commit comments