comparison mercurial/utils/procutil.py @ 43912:a89381e04c58

procutil: try and avoid angering CoreFoundation on macOS We've seen failures like this: objc[57662]: +[__NSCFConstantString initialize] may have been in progress in another thread when fork() was called. objc[57662]: +[__NSCFConstantString initialize] may have been in progress in another thread when fork() was called. We cannot safely call it or ignore it in the fork() child process. Crashing instead. Set a breakpoint on objc_initializeAfterForkError to debug. I think this is due to forking off some background processes during `hg update` or similar. I don't have any conclusive proof this is the fork() call that's to blame, but it's the most likely one since the regular `hg update` codepath uses the other fork() invocation (via workers) and we don't get this report from non-Google macOS users. Ugh. Differential Revision: https://phab.mercurial-scm.org/D7615
author Augie Fackler <augie@google.com>
date Thu, 05 Dec 2019 16:19:16 -0500
parents 5606e1cb4685
children ed684a82e29b
comparison
equal deleted inserted replaced
43911:f2de8dc9c52f 43912:a89381e04c58
421 if pycompat.sysplatform == b'OpenVMS' and rc & 1: 421 if pycompat.sysplatform == b'OpenVMS' and rc & 1:
422 rc = 0 422 rc = 0
423 return rc 423 return rc
424 424
425 425
426 def gui(): 426 _is_gui = None
427
428
429 def _gui():
427 '''Are we running in a GUI?''' 430 '''Are we running in a GUI?'''
428 if pycompat.isdarwin: 431 if pycompat.isdarwin:
429 if b'SSH_CONNECTION' in encoding.environ: 432 if b'SSH_CONNECTION' in encoding.environ:
430 # handle SSH access to a box where the user is logged in 433 # handle SSH access to a box where the user is logged in
431 return False 434 return False
435 else: 438 else:
436 # pure build; use a safe default 439 # pure build; use a safe default
437 return True 440 return True
438 else: 441 else:
439 return pycompat.iswindows or encoding.environ.get(b"DISPLAY") 442 return pycompat.iswindows or encoding.environ.get(b"DISPLAY")
443
444
445 def gui():
446 global _is_gui
447 if _is_gui is None:
448 _is_gui = _gui()
449 return _is_gui
440 450
441 451
442 def hgcmd(): 452 def hgcmd():
443 """Return the command used to execute current hg 453 """Return the command used to execute current hg
444 454
581 When `record_wait` is not None, the spawned process will not be fully 591 When `record_wait` is not None, the spawned process will not be fully
582 detached and the `record_wait` argument will be called with a the 592 detached and the `record_wait` argument will be called with a the
583 `Subprocess.wait` function for the spawned process. This is mostly 593 `Subprocess.wait` function for the spawned process. This is mostly
584 useful for developers that need to make sure the spawned process 594 useful for developers that need to make sure the spawned process
585 finished before a certain point. (eg: writing test)''' 595 finished before a certain point. (eg: writing test)'''
596 if pycompat.isdarwin:
597 # avoid crash in CoreFoundation in case another thread
598 # calls gui() while we're calling fork().
599 gui()
600
586 # double-fork to completely detach from the parent process 601 # double-fork to completely detach from the parent process
587 # based on http://code.activestate.com/recipes/278731 602 # based on http://code.activestate.com/recipes/278731
588 if record_wait is None: 603 if record_wait is None:
589 pid = os.fork() 604 pid = os.fork()
590 if pid: 605 if pid: