Mercurial > public > mercurial-scm > hg
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: |