mirror of
https://github.com/facebook/sapling.git
synced 2024-10-09 00:14:35 +03:00
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 297d89f2789e 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 stop queuing new connections and processing all pending connections before exit.
This commit is contained in:
parent
59177ba177
commit
863f8667b5
@ -477,11 +477,23 @@ class unixforkingservice(object):
|
||||
self._cleanup()
|
||||
|
||||
def _mainloop(self):
|
||||
exiting = False
|
||||
h = self._servicehandler
|
||||
while not h.shouldexit():
|
||||
while True:
|
||||
if not exiting and h.shouldexit():
|
||||
# clients can no longer connect() to the domain socket, so
|
||||
# we stop queuing new requests.
|
||||
# for requests that are queued (connect()-ed, but haven't been
|
||||
# accept()-ed), handle them before exit. otherwise, clients
|
||||
# waiting for recv() will receive ECONNRESET.
|
||||
self._unlinksocket()
|
||||
exiting = True
|
||||
try:
|
||||
ready = select.select([self._sock], [], [], h.pollinterval)[0]
|
||||
if not ready:
|
||||
# only exit if we completed all queued requests
|
||||
if exiting:
|
||||
break
|
||||
continue
|
||||
conn, _addr = self._sock.accept()
|
||||
except (select.error, socket.error) as inst:
|
||||
|
Loading…
Reference in New Issue
Block a user