changeset 29513:e5b4d79a9140

commandserver: backport handling of forking server from chgserver This is common between chg and vanilla forking server, so move it to commandserver and unify handle(). It would be debatable whether we really need gc.collect() or not, but that is beyond the scope of this series. Maybe we can remove gc.collect() once all resource deallocations are switched to context manager.
author Yuya Nishihara <yuya@tcha.org>
date Sat, 21 May 2016 15:23:21 +0900
parents 538d0003c9e0
children 280528245ecf
files hgext/chgserver.py mercurial/commandserver.py
diffstat 2 files changed, 13 insertions(+), 43 deletions(-) [+]
line wrap: on
line diff
--- a/hgext/chgserver.py	Sat May 21 15:18:23 2016 +0900
+++ b/hgext/chgserver.py	Sat May 21 15:23:21 2016 +0900
@@ -41,18 +41,15 @@
 from __future__ import absolute_import
 
 import errno
-import gc
 import hashlib
 import inspect
 import os
-import random
 import re
 import signal
 import struct
 import sys
 import threading
 import time
-import traceback
 
 from mercurial.i18n import _
 
@@ -535,46 +532,7 @@
                          'setenv': setenv,
                          'setumask': setumask})
 
-# copied from mercurial/commandserver.py
-class _requesthandler(socketserver.StreamRequestHandler):
-    def handle(self):
-        # 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.
-        os.setpgid(0, 0)
-        # change random state otherwise forked request handlers would have a
-        # same state inherited from parent.
-        random.seed()
-        ui = self.server.ui
-        sv = None
-        try:
-            sv = self._createcmdserver()
-            try:
-                sv.serve()
-            # handle exceptions that may be raised by command server. most of
-            # known exceptions are caught by dispatch.
-            except error.Abort as inst:
-                ui.warn(_('abort: %s\n') % inst)
-            except IOError as inst:
-                if inst.errno != errno.EPIPE:
-                    raise
-            except KeyboardInterrupt:
-                pass
-            finally:
-                sv.cleanup()
-        except: # re-raises
-            # also write traceback to error channel. otherwise client cannot
-            # see it because it is written to server's stderr by default.
-            if sv:
-                cerr = sv.cerr
-            else:
-                cerr = commandserver.channeledoutput(self.wfile, 'e')
-            traceback.print_exc(file=cerr)
-            raise
-        finally:
-            # trigger __del__ since ForkingMixIn uses os._exit
-            gc.collect()
-
+class _requesthandler(commandserver._requesthandler):
     def _createcmdserver(self):
         ui = self.server.ui
         repo = self.server.repo
--- a/mercurial/commandserver.py	Sat May 21 15:18:23 2016 +0900
+++ b/mercurial/commandserver.py	Sat May 21 15:23:21 2016 +0900
@@ -8,7 +8,9 @@
 from __future__ import absolute_import
 
 import errno
+import gc
 import os
+import random
 import struct
 import sys
 import traceback
@@ -338,6 +340,13 @@
 
 class _requesthandler(socketserver.StreamRequestHandler):
     def handle(self):
+        # 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.
+        os.setpgid(0, 0)
+        # change random state otherwise forked request handlers would have a
+        # same state inherited from parent.
+        random.seed()
         ui = self.server.ui
         sv = None
         try:
@@ -364,6 +373,9 @@
                 cerr = channeledoutput(self.wfile, 'e')
             traceback.print_exc(file=cerr)
             raise
+        finally:
+            # trigger __del__ since ForkingMixIn uses os._exit
+            gc.collect()
 
     def _createcmdserver(self):
         ui = self.server.ui