summaryrefslogtreecommitdiffstats
path: root/platform_utils.py
diff options
context:
space:
mode:
authorTheodore Dubois <tbodt@google.com>2019-12-17 17:51:29 -0800
committerMike Frysinger <vapier@google.com>2019-12-18 21:16:23 +0000
commit1e01a7444536b4865feb94c398b68a936a463ddc (patch)
tree7a3ee434a9b8fdd00d3aaebe5e22aab432d8c5a8 /platform_utils.py
parent7c321f1bf6c19efdeae1042acfff5933ab4b376f (diff)
downloadgit-repo-1e01a7444536b4865feb94c398b68a936a463ddc.tar.gz
Port _FileDescriptorStreamsNonBlocking to use poll()
select() has a limit of FD_SETSIZE file descriptors. If you run repo sync -j500 you'll pretty quickly hit this limit and get "file descriptor out of range for select" errors. poll() has no such limit. Change-Id: I21f350e472bda1db03dcbcc437645c23dbc7a901 Reviewed-on: https://gerrit-review.googlesource.com/c/git-repo/+/248852 Reviewed-by: Mike Frysinger <vapier@google.com> Tested-by: Theodore Dubois <tbodt@google.com>
Diffstat (limited to 'platform_utils.py')
-rw-r--r--platform_utils.py18
1 files changed, 15 insertions, 3 deletions
diff --git a/platform_utils.py b/platform_utils.py
index 6684ebc8..0b139dbc 100644
--- a/platform_utils.py
+++ b/platform_utils.py
@@ -90,6 +90,11 @@ class _FileDescriptorStreamsNonBlocking(FileDescriptorStreams):
90 """ Implementation of FileDescriptorStreams for platforms that support 90 """ Implementation of FileDescriptorStreams for platforms that support
91 non blocking I/O. 91 non blocking I/O.
92 """ 92 """
93 def __init__(self):
94 super(_FileDescriptorStreamsNonBlocking, self).__init__()
95 self._poll = select.poll()
96 self._fd_to_stream = {}
97
93 class Stream(object): 98 class Stream(object):
94 """ Encapsulates a file descriptor """ 99 """ Encapsulates a file descriptor """
95 def __init__(self, fd, dest, std_name): 100 def __init__(self, fd, dest, std_name):
@@ -113,11 +118,18 @@ class _FileDescriptorStreamsNonBlocking(FileDescriptorStreams):
113 self.fd.close() 118 self.fd.close()
114 119
115 def _create_stream(self, fd, dest, std_name): 120 def _create_stream(self, fd, dest, std_name):
116 return self.Stream(fd, dest, std_name) 121 stream = self.Stream(fd, dest, std_name)
122 self._fd_to_stream[stream.fileno()] = stream
123 self._poll.register(stream, select.POLLIN)
124 return stream
125
126 def remove(self, stream):
127 self._poll.unregister(stream)
128 del self._fd_to_stream[stream.fileno()]
129 super(_FileDescriptorStreamsNonBlocking, self).remove(stream)
117 130
118 def select(self): 131 def select(self):
119 ready_streams, _, _ = select.select(self.streams, [], []) 132 return [self._fd_to_stream[fd] for fd, _ in self._poll.poll()]
120 return ready_streams
121 133
122 134
123class _FileDescriptorStreamsThreads(FileDescriptorStreams): 135class _FileDescriptorStreamsThreads(FileDescriptorStreams):