background: disable gc before forking

Summary:
We encountered an issue where gc kicked in after forking the Python
process. This cause it to trigger some Rust drop logic which hung because some
cross thread locks were not in a good state. Let's just disable gc during the
fork and only reenable it in the parent process.

Reviewed By: quark-zju

Differential Revision: D22855986

fbshipit-source-id: c3e99fb000bcd4cc141848e6362bb7773d0aad3d
This commit is contained in:
Durham Goode 2020-07-31 09:16:59 -07:00 committed by Facebook GitHub Bot
parent 417d61f4b6
commit c35b8088ef

View File

@ -9,6 +9,7 @@ from __future__ import absolute_import
import contextlib
import errno
import gc
import os
import subprocess
import time
@ -55,6 +56,11 @@ else:
# "os.fork()".
# 2. The "pid" variable cannot be used in the "finally" block.
try:
# Disable gc so the child process doesn't accidentally trigger it
# and try to collect native objects that might depend on locks held
# by other threads.
gc.disable()
# double-fork to completely detach from the parent process
# based on http://code.activestate.com/recipes/278731
pid = os.fork()
@ -116,6 +122,7 @@ else:
# mission accomplished, this child needs to exit and not
# continue the hg process here.
os._exit(returncode)
gc.enable()
def runshellcommand(script, env):