Patchwork D7615: procutil: try and avoid angering CoreFoundation on macOS

login
register
mail settings
Submitter phabricator
Date Dec. 12, 2019, 5:38 p.m.
Message ID <differential-rev-PHID-DREV-awnun2pbtjsdxvjoount-req@mercurial-scm.org>
Download mbox | patch
Permalink /patch/43755/
State Superseded
Headers show

Comments

phabricator - Dec. 12, 2019, 5:38 p.m.
durin42 created this revision.
Herald added a subscriber: mercurial-devel.
Herald added a reviewer: hg-reviewers.

REVISION SUMMARY
  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.

REPOSITORY
  rHG Mercurial

BRANCH
  default

REVISION DETAIL
  https://phab.mercurial-scm.org/D7615

AFFECTED FILES
  mercurial/utils/procutil.py

CHANGE DETAILS




To: durin42, #hg-reviewers
Cc: mercurial-devel

Patch

diff --git a/mercurial/utils/procutil.py b/mercurial/utils/procutil.py
--- a/mercurial/utils/procutil.py
+++ b/mercurial/utils/procutil.py
@@ -423,7 +423,10 @@ 
     return rc
 
 
-def gui():
+_is_gui = None
+
+
+def _gui():
     '''Are we running in a GUI?'''
     if pycompat.isdarwin:
         if b'SSH_CONNECTION' in encoding.environ:
@@ -439,6 +442,13 @@ 
         return pycompat.iswindows or encoding.environ.get(b"DISPLAY")
 
 
+def gui():
+    global _is_gui
+    if _is_gui is None:
+        _is_gui = _gui()
+    return _is_gui
+
+
 def hgcmd():
     """Return the command used to execute current hg
 
@@ -562,6 +572,11 @@ 
         cmd, env, shell=False, stdout=None, stderr=None, ensurestart=True
     ):
         '''Spawn a command without waiting for it to finish.'''
+        if pycompat.isdarwin:
+            # avoid crash in CoreFoundation in case another thread
+            # calls gui() while we're calling fork().
+            gui()
+
         # double-fork to completely detach from the parent process
         # based on http://code.activestate.com/recipes/278731
         pid = os.fork()