# HG changeset patch
# User Jun Wu <qu...@fb.com>
# Date 1485794838 0
#      Mon Jan 30 16:47:18 2017 +0000
# Node ID 0f9c5c49ad7ac321f6fecb4ca90121969bb038d4
# Parent  ea5353feeec3c2eddd7e4acfd398baddaf37b3e4
# Available At https://bitbucket.org/quark-zju/hg-draft
#              hg pull https://bitbucket.org/quark-zju/hg-draft -r 0f9c5c49ad7a
commandserver: handle backlog before exiting

Previously, when a chg server is exiting, it does not handle connected
clients so clients may get ECONNRESET and crash:

  1. client connect() # success
  2. server shouldexit = True and exit
  3. client recv() # ECONNRESET

d7875bfbfccb makes this race condition easier to reproduce if a lot of short
chg commands are started in parallel.

This patch fixes the above issue by unlinking the socket path to prevent new
connections and handling all pending connections before exiting.

diff --git a/mercurial/commandserver.py b/mercurial/commandserver.py
--- a/mercurial/commandserver.py
+++ b/mercurial/commandserver.py
@@ -412,5 +412,9 @@ class unixservicehandler(object):
 
     def unlinksocket(self, address):
-        os.unlink(address)
+        try:
+            os.unlink(address)
+        except OSError as ex:
+            if ex.errno != errno.ENOENT:
+                raise
 
     def printbanner(self, address):
@@ -471,9 +475,17 @@ class unixforkingservice(object):
 
     def _mainloop(self):
+        exiting = False
         h = self._servicehandler
-        while not h.shouldexit():
+        while True:
+            if not exiting and h.shouldexit():
+                # prevent accepting new connections
+                self._servicehandler.unlinksocket(self.address)
+                exiting = True
             try:
                 ready = select.select([self._sock], [], [], h.pollinterval)[0]
                 if not ready:
+                    # only exit if we have no more connections to handle
+                    if exiting:
+                        break
                     continue
                 conn, _addr = self._sock.accept()
_______________________________________________
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel

Reply via email to