mercurial/worker.py
changeset 30521 86cd09bc13ba
parent 30425 03f7aa2bd0e3
child 30635 a150173da1c1
--- a/mercurial/worker.py	Thu Nov 24 00:48:40 2016 +0000
+++ b/mercurial/worker.py	Thu Nov 24 01:15:34 2016 +0000
@@ -15,6 +15,7 @@
 from .i18n import _
 from . import (
     error,
+    scmutil,
     util,
 )
 
@@ -132,15 +133,26 @@
         if pid == 0:
             signal.signal(signal.SIGINT, oldhandler)
             signal.signal(signal.SIGCHLD, oldchldhandler)
-            try:
+
+            def workerfunc():
                 os.close(rfd)
                 for i, item in func(*(staticargs + (pargs,))):
                     os.write(wfd, '%d %s\n' % (i, item))
-                os._exit(0)
+
+            # make sure we use os._exit in all code paths. otherwise the worker
+            # may do some clean-ups which could cause surprises like deadlock.
+            # see sshpeer.cleanup for example.
+            try:
+                scmutil.callcatch(ui, workerfunc)
             except KeyboardInterrupt:
                 os._exit(255)
-                # other exceptions are allowed to propagate, we rely
-                # on lock.py's pid checks to avoid release callbacks
+            except: # never return, therefore no re-raises
+                try:
+                    ui.traceback()
+                finally:
+                    os._exit(255)
+            else:
+                os._exit(0)
         pids.add(pid)
     os.close(wfd)
     fp = os.fdopen(rfd, 'rb', 0)