commandserver: separate initialization and cleanup of forked process
authorYuya Nishihara <yuya@tcha.org>
Sun, 22 May 2016 13:53:32 +0900
changeset 29586 42cdba9cfee4
parent 29585 6ed452d0f1f1
child 29587 536eec443b4a
commandserver: separate initialization and cleanup of forked process Separated _initworkerprocess() and _serverequest() can be reused when implementing a prefork service.
mercurial/commandserver.py
--- a/mercurial/commandserver.py	Sat May 21 18:14:13 2016 +0900
+++ b/mercurial/commandserver.py	Sun May 22 13:53:32 2016 +0900
@@ -342,7 +342,7 @@
             sv.cleanup()
             _restoreio(ui, fin, fout)
 
-def _serverequest(ui, repo, conn, createcmdserver):
+def _initworkerprocess():
     # use a different process group from the master process, making this
     # process pass kernel "is_current_pgrp_orphaned" check so signals like
     # SIGTSTP, SIGTTIN, SIGTTOU are not ignored.
@@ -351,6 +351,7 @@
     # same state inherited from parent.
     random.seed()
 
+def _serverequest(ui, repo, conn, createcmdserver):
     fin = conn.makefile('rb')
     fout = conn.makefile('wb')
     sv = None
@@ -385,8 +386,6 @@
         except IOError as inst:
             if inst.errno != errno.EPIPE:
                 raise
-        # trigger __del__ since ForkingMixIn uses os._exit
-        gc.collect()
 
 class unixservicehandler(object):
     """Set of pluggable operations for unix-mode services
@@ -517,8 +516,12 @@
 
     def _serveworker(self, conn):
         signal.signal(signal.SIGCHLD, self._oldsigchldhandler)
+        _initworkerprocess()
         h = self._servicehandler
-        _serverequest(self.ui, self.repo, conn, h.createcmdserver)
+        try:
+            _serverequest(self.ui, self.repo, conn, h.createcmdserver)
+        finally:
+            gc.collect()  # trigger __del__ since worker process uses os._exit
 
 _servicemap = {
     'pipe': pipeservice,