Patchwork [2,of,4] commandserver: separate initialization and cleanup of forked process

login
register
mail settings
Submitter Yuya Nishihara
Date July 17, 2016, 2:03 p.m.
Message ID <57f747c19205d4dc0e1f.1468764180@mimosa>
Download mbox | patch
Permalink /patch/15911/
State Accepted
Headers show

Comments

Yuya Nishihara - July 17, 2016, 2:03 p.m.
# HG changeset patch
# User Yuya Nishihara <yuya@tcha.org>
# Date 1463892812 -32400
#      Sun May 22 13:53:32 2016 +0900
# Node ID 57f747c19205d4dc0e1f0813860d4c625f400b67
# Parent  3df2dc92d3a7c47cd79bd7ad44d6c3bf5679dbda
commandserver: separate initialization and cleanup of forked process

Separated _initworkerprocess() and _serverequest() can be reused when
implementing a prefork service.

Patch

diff --git a/mercurial/commandserver.py b/mercurial/commandserver.py
--- a/mercurial/commandserver.py
+++ b/mercurial/commandserver.py
@@ -339,7 +339,7 @@  class pipeservice(object):
             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.
@@ -348,6 +348,7 @@  def _serverequest(ui, repo, conn, create
     # same state inherited from parent.
     random.seed()
 
+def _serverequest(ui, repo, conn, createcmdserver):
     fin = conn.makefile('rb')
     fout = conn.makefile('wb')
     sv = None
@@ -382,8 +383,6 @@  def _serverequest(ui, repo, conn, create
         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
@@ -514,8 +513,12 @@  class unixforkingservice(object):
 
     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,