commandserver: manually create file objects from socket
authorYuya Nishihara <yuya@tcha.org>
Sun, 22 May 2016 12:44:25 +0900
changeset 29542 6011ad3b0a42
parent 29541 9631ff5ebbeb
child 29543 d74b8a4fde3b
commandserver: manually create file objects from socket Prepares for moving away from SocketServer. See the subsequent patches for why.
hgext/chgserver.py
mercurial/commandserver.py
--- a/hgext/chgserver.py	Wed Jul 13 10:46:26 2016 +0200
+++ b/hgext/chgserver.py	Sun May 22 12:44:25 2016 +0900
@@ -533,10 +533,10 @@
                          'setumask': setumask})
 
 class _requesthandler(commandserver._requesthandler):
-    def _createcmdserver(self):
+    def _createcmdserver(self, conn, fin, fout):
         ui = self.server.ui
         repo = self.server.repo
-        return chgcmdserver(ui, repo, self.rfile, self.wfile, self.connection,
+        return chgcmdserver(ui, repo, fin, fout, conn,
                             self.server.hashstate, self.server.baseaddress)
 
 def _tempaddress(address):
--- a/mercurial/commandserver.py	Wed Jul 13 10:46:26 2016 +0200
+++ b/mercurial/commandserver.py	Sun May 22 12:44:25 2016 +0900
@@ -338,7 +338,7 @@
             sv.cleanup()
             _restoreio(ui, fin, fout)
 
-class _requesthandler(socketserver.StreamRequestHandler):
+class _requesthandler(socketserver.BaseRequestHandler):
     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
@@ -348,9 +348,13 @@
         # same state inherited from parent.
         random.seed()
         ui = self.server.ui
+
+        conn = self.request
+        fin = conn.makefile('rb')
+        fout = conn.makefile('wb')
         sv = None
         try:
-            sv = self._createcmdserver()
+            sv = self._createcmdserver(conn, fin, fout)
             try:
                 sv.serve()
             # handle exceptions that may be raised by command server. most of
@@ -370,17 +374,23 @@
             if sv:
                 cerr = sv.cerr
             else:
-                cerr = channeledoutput(self.wfile, 'e')
+                cerr = channeledoutput(fout, 'e')
             traceback.print_exc(file=cerr)
             raise
         finally:
+            fin.close()
+            try:
+                fout.close()  # implicit flush() may cause another EPIPE
+            except IOError as inst:
+                if inst.errno != errno.EPIPE:
+                    raise
             # trigger __del__ since ForkingMixIn uses os._exit
             gc.collect()
 
-    def _createcmdserver(self):
+    def _createcmdserver(self, conn, fin, fout):
         ui = self.server.ui
         repo = self.server.repo
-        return server(ui, repo, self.rfile, self.wfile)
+        return server(ui, repo, fin, fout)
 
 class unixservice(object):
     """