diff --git a/Lib/multiprocessing/connection.py b/Lib/multiprocessing/connection.py --- a/Lib/multiprocessing/connection.py +++ b/Lib/multiprocessing/connection.py @@ -861,6 +861,30 @@ return [o for o in object_list if o in ready_objects] else: + def _poll(fds, timeout): + # Note: fds might be a list of fds or Connection instances. + try: + return select.select(fds, [], [], timeout)[0] + except ValueError: + # ValueError might be raised by select() if we hit FD_SETSIZE, + # in which case we try to use poll(). + # We have to keep in mind that a list of Connection objects + # may be passed though. + # Whereas select() is able to interpret and return them poll() + # won't (a list of integers will be returned instead). + # If that's the case we just give up and reraise ValueError. + if not hasattr(select, 'poll') \ + or not all((isinstance(x, int) for x in fds)): + raise + if timeout is not None: + timeout = int(timeout) * 1000 # timeout is in milliseconds + pollster = select.poll() + for fd in fds: + pollster.register(fd, select.POLLIN) + ret = pollster.poll(timeout) + for fd in fds: + pollster.unregister(fd) + return [x[0] for x in ret] def wait(object_list, timeout=None): ''' @@ -870,12 +894,12 @@ ''' if timeout is not None: if timeout <= 0: - return select.select(object_list, [], [], 0)[0] + return _poll(object_list, 0) else: deadline = time.time() + timeout while True: try: - return select.select(object_list, [], [], timeout)[0] + return _poll(object_list, timeout) except OSError as e: if e.errno != errno.EINTR: raise