# HG changeset patch # User Jun Wu # Date 2017-07-15 03:26:21 # Node ID 27d23fe32887279db649eccae244f261452be7ac # Parent 5d0c0c8d2929be8fb23c722ec2df21b149dc8fc2 commandserver: use selectors2 Previously, commandserver was using select.select. That could have issue if _sock.fileno() >= FD_SETSIZE (usually 1024), which raises: ValueError: filedescriptor out of range in select() We got that in production today, although it's the code opening that many files to blame, it seems better for commandserver to work in this case. There are multiple way to "solve" it, like preserving a fd with a small number and swap it with sock using dup2(). But upgrading to a modern selector supported by the system seems to be the most correct way. diff --git a/mercurial/commandserver.py b/mercurial/commandserver.py --- a/mercurial/commandserver.py +++ b/mercurial/commandserver.py @@ -22,6 +22,7 @@ from . import ( encoding, error, pycompat, + selectors2, util, ) @@ -476,6 +477,8 @@ class unixforkingservice(object): def _mainloop(self): exiting = False h = self._servicehandler + selector = selectors2.DefaultSelector() + selector.register(self._sock, selectors2.EVENT_READ) while True: if not exiting and h.shouldexit(): # clients can no longer connect() to the domain socket, so @@ -486,7 +489,7 @@ class unixforkingservice(object): self._unlinksocket() exiting = True try: - ready = select.select([self._sock], [], [], h.pollinterval)[0] + ready = selector.select(timeout=h.pollinterval) if not ready: # only exit if we completed all queued requests if exiting: