Bug 1875768 - Call the appropriate postfork handler on MacOS r=glandium, a=dmeehan

Differential Revision: https://phabricator.services.mozilla.com/D212231
This commit is contained in:
Paul Bone 2024-07-04 03:51:07 +00:00
parent 40ddfb59b9
commit cd1ef58bda
2 changed files with 32 additions and 3 deletions

View file

@ -1550,6 +1550,9 @@ static bool malloc_init_hard();
FORK_HOOK void _malloc_prefork(void); FORK_HOOK void _malloc_prefork(void);
FORK_HOOK void _malloc_postfork_parent(void); FORK_HOOK void _malloc_postfork_parent(void);
FORK_HOOK void _malloc_postfork_child(void); FORK_HOOK void _malloc_postfork_child(void);
# ifdef XP_DARWIN
FORK_HOOK void _malloc_postfork(void);
# endif
#endif #endif
// End forward declarations. // 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 // 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 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. // 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; 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 FORK_HOOK
void _malloc_prefork(void) MOZ_NO_THREAD_SAFETY_ANALYSIS { void _malloc_prefork(void) MOZ_NO_THREAD_SAFETY_ANALYSIS {
// Acquire all mutexes in a safe order. // Acquire all mutexes in a safe order.
gArenas.mLock.Lock(); gArenas.mLock.Lock();
gForkingThread = pthread_self(); gForkingThread = pthread_self();
# ifdef XP_DARWIN
gForkingProcess = getpid();
# endif
for (auto arena : gArenas.iter()) { for (auto arena : gArenas.iter()) {
if (arena->mLock.LockIsEnabled()) { if (arena->mLock.LockIsEnabled()) {
@ -5229,7 +5242,22 @@ void _malloc_postfork_child(void) {
gArenas.mLock.Init(); 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. // End library-private functions.
// *************************************************************************** // ***************************************************************************

View file

@ -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) {} 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_prefork(void);
extern void _malloc_postfork_child(void); extern void _malloc_postfork(void);
static void zone_force_lock(malloc_zone_t* zone) { static void zone_force_lock(malloc_zone_t* zone) {
// /!\ This calls into mozjemalloc. It works because we're linked in the // /!\ 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) { static void zone_force_unlock(malloc_zone_t* zone) {
// /!\ This calls into mozjemalloc. It works because we're linked in the // /!\ This calls into mozjemalloc. It works because we're linked in the
// same library. // same library.
_malloc_postfork_child(); _malloc_postfork();
} }
static void zone_statistics(malloc_zone_t* zone, malloc_statistics_t* stats) { static void zone_statistics(malloc_zone_t* zone, malloc_statistics_t* stats) {