diff --git a/memory/build/mozjemalloc.cpp b/memory/build/mozjemalloc.cpp index 2b158a5762fb..f17f99356800 100644 --- a/memory/build/mozjemalloc.cpp +++ b/memory/build/mozjemalloc.cpp @@ -1550,6 +1550,9 @@ static bool malloc_init_hard(); FORK_HOOK void _malloc_prefork(void); FORK_HOOK void _malloc_postfork_parent(void); FORK_HOOK void _malloc_postfork_child(void); +# ifdef XP_DARWIN +FORK_HOOK void _malloc_postfork(void); +# endif #endif // End forward declarations. @@ -5178,13 +5181,23 @@ inline void MozJemalloc::moz_set_max_dirty_page_modifier(int32_t aModifier) { // state for the child is if fork is called from the main thread only. Or the // child must not use them, eg it should call exec(). We attempt to prevent the // child for accessing these arenas by refusing to re-initialise them. +// +// This is only accessed in the fork handlers while gArenas.mLock is held. static pthread_t gForkingThread; +# ifdef XP_DARWIN +// This is only accessed in the fork handlers while gArenas.mLock is held. +static pid_t gForkingProcess; +# endif + FORK_HOOK void _malloc_prefork(void) MOZ_NO_THREAD_SAFETY_ANALYSIS { // Acquire all mutexes in a safe order. gArenas.mLock.Lock(); gForkingThread = pthread_self(); +# ifdef XP_DARWIN + gForkingProcess = getpid(); +# endif for (auto arena : gArenas.iter()) { if (arena->mLock.LockIsEnabled()) { @@ -5229,7 +5242,22 @@ void _malloc_postfork_child(void) { gArenas.mLock.Init(); } -#endif // XP_WIN + +# ifdef XP_DARWIN +FORK_HOOK +void _malloc_postfork(void) { + // On MacOS we need to check if this is running in the parent or child + // process. + bool is_in_parent = getpid() == gForkingProcess; + gForkingProcess = 0; + if (is_in_parent) { + _malloc_postfork_parent(); + } else { + _malloc_postfork_child(); + } +} +# endif // XP_DARWIN +#endif // ! XP_WIN // End library-private functions. // *************************************************************************** diff --git a/memory/build/zone.c b/memory/build/zone.c index 7311ccf27bc4..eaabcf01bdbf 100644 --- a/memory/build/zone.c +++ b/memory/build/zone.c @@ -232,8 +232,9 @@ static void zone_print(malloc_zone_t* zone, boolean_t verbose) {} static void zone_log(malloc_zone_t* zone, void* address) {} +// On Darwin the postfork handler is called in both the parent and the child. extern void _malloc_prefork(void); -extern void _malloc_postfork_child(void); +extern void _malloc_postfork(void); static void zone_force_lock(malloc_zone_t* zone) { // /!\ This calls into mozjemalloc. It works because we're linked in the @@ -244,7 +245,7 @@ static void zone_force_lock(malloc_zone_t* zone) { static void zone_force_unlock(malloc_zone_t* zone) { // /!\ This calls into mozjemalloc. It works because we're linked in the // same library. - _malloc_postfork_child(); + _malloc_postfork(); } static void zone_statistics(malloc_zone_t* zone, malloc_statistics_t* stats) {