changeset 32276:c8b9943c07eb

commandserver: move "listen" responsibility from service to handler This enables chg to replace a server socket in an atomic way: 1. bind to a temp address 2. listen 3. rename Currently 3 happens before 2 so a client may see the socket file but fails to connect to it.
author Jun Wu <quark@fb.com>
date Sun, 30 Apr 2017 11:08:27 -0700
parents cf415777a22c
children 1ada3d18e7fb
files mercurial/chgserver.py mercurial/commandserver.py
diffstat 2 files changed, 3 insertions(+), 1 deletions(-) [+]
line wrap: on
line diff
--- a/mercurial/chgserver.py	Mon May 08 15:31:34 2017 -0700
+++ b/mercurial/chgserver.py	Sun Apr 30 11:08:27 2017 -0700
@@ -44,6 +44,7 @@
 import inspect
 import os
 import re
+import socket
 import struct
 import time
 
@@ -516,6 +517,7 @@
         tempaddress = _tempaddress(self._realaddress)
         util.bindunixsocket(sock, tempaddress)
         self._socketstat = os.stat(tempaddress)
+        sock.listen(socket.SOMAXCONN)
         # rename will replace the old socket file if exists atomically. the
         # old server will detect ownership change and exit.
         util.rename(tempaddress, self._realaddress)
--- a/mercurial/commandserver.py	Mon May 08 15:31:34 2017 -0700
+++ b/mercurial/commandserver.py	Sun Apr 30 11:08:27 2017 -0700
@@ -409,6 +409,7 @@
 
     def bindsocket(self, sock, address):
         util.bindunixsocket(sock, address)
+        sock.listen(socket.SOMAXCONN)
 
     def unlinksocket(self, address):
         os.unlink(address)
@@ -452,7 +453,6 @@
     def init(self):
         self._sock = socket.socket(socket.AF_UNIX)
         self._servicehandler.bindsocket(self._sock, self.address)
-        self._sock.listen(socket.SOMAXCONN)
         o = signal.signal(signal.SIGCHLD, self._sigchldhandler)
         self._oldsigchldhandler = o
         self._servicehandler.printbanner(self.address)