#30014: refactor poll-related classes by giampaolo · Pull Request #1035 · python/cpython
Expand Up
@@ -339,92 +339,86 @@ def select(self, timeout=None):
return ready
if hasattr(select, 'poll'): class _PollLikeSelector(_BaseSelectorImpl): """Base class shared between poll, epoll and devpoll selectors.""" _selector_cls = None
class PollSelector(_BaseSelectorImpl): """Poll-based selector.""" def __init__(self): super().__init__() self._selector = self._selector_cls()
def __init__(self): super().__init__() self._poll = select.poll() def register(self, fileobj, events, data=None): key = super().register(fileobj, events, data) poller_events = 0 if events & EVENT_READ: poller_events |= self._EVENT_READ if events & EVENT_WRITE: poller_events |= self._EVENT_WRITE try: self._selector.register(key.fd, poller_events) except Exception: super().unregister(fileobj) raise return key
def register(self, fileobj, events, data=None): key = super().register(fileobj, events, data) poll_events = 0 if events & EVENT_READ: poll_events |= select.POLLIN if events & EVENT_WRITE: poll_events |= select.POLLOUT self._poll.register(key.fd, poll_events) return key def unregister(self, fileobj): key = super().unregister(fileobj) try: self._selector.unregister(key.fd) except OSError: # This can happen if the FD was closed since it # was registered. pass return key
def unregister(self, fileobj): key = super().unregister(fileobj) self._poll.unregister(key.fd) return key def select(self, timeout=None): # This is shared between poll() and epoll(). # epoll() has a different signature and handling of timeout parameter. if timeout is None: timeout = None elif timeout <= 0: timeout = 0 else: # poll() has a resolution of 1 millisecond, round away from # zero to wait *at least* timeout seconds. timeout = math.ceil(timeout * 1e3) ready = [] try: fd_event_list = self._selector.poll(timeout) except InterruptedError: return ready for fd, event in fd_event_list: events = 0 if event & ~self._EVENT_READ: events |= EVENT_WRITE if event & ~self._EVENT_WRITE: events |= EVENT_READ
def select(self, timeout=None): if timeout is None: timeout = None elif timeout <= 0: timeout = 0 else: # poll() has a resolution of 1 millisecond, round away from # zero to wait *at least* timeout seconds. timeout = math.ceil(timeout * 1e3) ready = [] try: fd_event_list = self._poll.poll(timeout) except InterruptedError: return ready for fd, event in fd_event_list: events = 0 if event & ~select.POLLIN: events |= EVENT_WRITE if event & ~select.POLLOUT: events |= EVENT_READ key = self._key_from_fd(fd) if key: ready.append((key, events & key.events)) return ready
key = self._key_from_fd(fd) if key: ready.append((key, events & key.events)) return ready
if hasattr(select, 'poll'):
class PollSelector(_PollLikeSelector): """Poll-based selector.""" _selector_cls = select.poll _EVENT_READ = select.POLLIN _EVENT_WRITE = select.POLLOUT
if hasattr(select, 'epoll'):
class EpollSelector(_BaseSelectorImpl): class EpollSelector(_PollLikeSelector): """Epoll-based selector."""
def __init__(self): super().__init__() self._epoll = select.epoll() _selector_cls = select.epoll _EVENT_READ = select.EPOLLIN _EVENT_WRITE = select.EPOLLOUT
def fileno(self): return self._epoll.fileno()
def register(self, fileobj, events, data=None): key = super().register(fileobj, events, data) epoll_events = 0 if events & EVENT_READ: epoll_events |= select.EPOLLIN if events & EVENT_WRITE: epoll_events |= select.EPOLLOUT try: self._epoll.register(key.fd, epoll_events) except BaseException: super().unregister(fileobj) raise return key
def unregister(self, fileobj): key = super().unregister(fileobj) try: self._epoll.unregister(key.fd) except OSError: # This can happen if the FD was closed since it # was registered. pass return key return self._selector.fileno()
def select(self, timeout=None): if timeout is None: Expand All @@ -443,7 +437,7 @@ def select(self, timeout=None):
ready = [] try: fd_event_list = self._epoll.poll(timeout, max_ev) fd_event_list = self._selector.poll(timeout, max_ev) except InterruptedError: return ready for fd, event in fd_event_list: Expand All @@ -459,65 +453,23 @@ def select(self, timeout=None): return ready
def close(self): self._epoll.close() self._selector.close() super().close()
if hasattr(select, 'devpoll'):
class DevpollSelector(_BaseSelectorImpl): class DevpollSelector(_PollLikeSelector): """Solaris /dev/poll selector."""
def __init__(self): super().__init__() self._devpoll = select.devpoll() _selector_cls = select.devpoll _EVENT_READ = select.POLLIN _EVENT_WRITE = select.POLLOUT
def fileno(self): return self._devpoll.fileno()
def register(self, fileobj, events, data=None): key = super().register(fileobj, events, data) poll_events = 0 if events & EVENT_READ: poll_events |= select.POLLIN if events & EVENT_WRITE: poll_events |= select.POLLOUT self._devpoll.register(key.fd, poll_events) return key
def unregister(self, fileobj): key = super().unregister(fileobj) self._devpoll.unregister(key.fd) return key
def select(self, timeout=None): if timeout is None: timeout = None elif timeout <= 0: timeout = 0 else: # devpoll() has a resolution of 1 millisecond, round away from # zero to wait *at least* timeout seconds. timeout = math.ceil(timeout * 1e3) ready = [] try: fd_event_list = self._devpoll.poll(timeout) except InterruptedError: return ready for fd, event in fd_event_list: events = 0 if event & ~select.POLLIN: events |= EVENT_WRITE if event & ~select.POLLOUT: events |= EVENT_READ
key = self._key_from_fd(fd) if key: ready.append((key, events & key.events)) return ready return self._selector.fileno()
def close(self): self._devpoll.close() self._selector.close() super().close()
Expand All @@ -528,23 +480,23 @@ class KqueueSelector(_BaseSelectorImpl):
def __init__(self): super().__init__() self._kqueue = select.kqueue() self._selector = select.kqueue()
def fileno(self): return self._kqueue.fileno() return self._selector.fileno()
def register(self, fileobj, events, data=None): key = super().register(fileobj, events, data) try: if events & EVENT_READ: kev = select.kevent(key.fd, select.KQ_FILTER_READ, select.KQ_EV_ADD) self._kqueue.control([kev], 0, 0) self._selector.control([kev], 0, 0) if events & EVENT_WRITE: kev = select.kevent(key.fd, select.KQ_FILTER_WRITE, select.KQ_EV_ADD) self._kqueue.control([kev], 0, 0) except BaseException: self._selector.control([kev], 0, 0) except Exception: super().unregister(fileobj) raise return key Expand All @@ -555,7 +507,7 @@ def unregister(self, fileobj): kev = select.kevent(key.fd, select.KQ_FILTER_READ, select.KQ_EV_DELETE) try: self._kqueue.control([kev], 0, 0) self._selector.control([kev], 0, 0) except OSError: # This can happen if the FD was closed since it # was registered. Expand All @@ -564,7 +516,7 @@ def unregister(self, fileobj): kev = select.kevent(key.fd, select.KQ_FILTER_WRITE, select.KQ_EV_DELETE) try: self._kqueue.control([kev], 0, 0) self._selector.control([kev], 0, 0) except OSError: # See comment above. pass Expand All @@ -575,7 +527,7 @@ def select(self, timeout=None): max_ev = len(self._fd_to_key) ready = [] try: kev_list = self._kqueue.control(None, max_ev, timeout) kev_list = self._selector.control(None, max_ev, timeout) except InterruptedError: return ready for kev in kev_list: Expand All @@ -593,7 +545,7 @@ def select(self, timeout=None): return ready
def close(self): self._kqueue.close() self._selector.close() super().close()
Expand Down
if hasattr(select, 'poll'): class _PollLikeSelector(_BaseSelectorImpl): """Base class shared between poll, epoll and devpoll selectors.""" _selector_cls = None
class PollSelector(_BaseSelectorImpl): """Poll-based selector.""" def __init__(self): super().__init__() self._selector = self._selector_cls()
def __init__(self): super().__init__() self._poll = select.poll() def register(self, fileobj, events, data=None): key = super().register(fileobj, events, data) poller_events = 0 if events & EVENT_READ: poller_events |= self._EVENT_READ if events & EVENT_WRITE: poller_events |= self._EVENT_WRITE try: self._selector.register(key.fd, poller_events) except Exception: super().unregister(fileobj) raise return key
def register(self, fileobj, events, data=None): key = super().register(fileobj, events, data) poll_events = 0 if events & EVENT_READ: poll_events |= select.POLLIN if events & EVENT_WRITE: poll_events |= select.POLLOUT self._poll.register(key.fd, poll_events) return key def unregister(self, fileobj): key = super().unregister(fileobj) try: self._selector.unregister(key.fd) except OSError: # This can happen if the FD was closed since it # was registered. pass return key
def unregister(self, fileobj): key = super().unregister(fileobj) self._poll.unregister(key.fd) return key def select(self, timeout=None): # This is shared between poll() and epoll(). # epoll() has a different signature and handling of timeout parameter. if timeout is None: timeout = None elif timeout <= 0: timeout = 0 else: # poll() has a resolution of 1 millisecond, round away from # zero to wait *at least* timeout seconds. timeout = math.ceil(timeout * 1e3) ready = [] try: fd_event_list = self._selector.poll(timeout) except InterruptedError: return ready for fd, event in fd_event_list: events = 0 if event & ~self._EVENT_READ: events |= EVENT_WRITE if event & ~self._EVENT_WRITE: events |= EVENT_READ
def select(self, timeout=None): if timeout is None: timeout = None elif timeout <= 0: timeout = 0 else: # poll() has a resolution of 1 millisecond, round away from # zero to wait *at least* timeout seconds. timeout = math.ceil(timeout * 1e3) ready = [] try: fd_event_list = self._poll.poll(timeout) except InterruptedError: return ready for fd, event in fd_event_list: events = 0 if event & ~select.POLLIN: events |= EVENT_WRITE if event & ~select.POLLOUT: events |= EVENT_READ key = self._key_from_fd(fd) if key: ready.append((key, events & key.events)) return ready
key = self._key_from_fd(fd) if key: ready.append((key, events & key.events)) return ready
if hasattr(select, 'poll'):
class PollSelector(_PollLikeSelector): """Poll-based selector.""" _selector_cls = select.poll _EVENT_READ = select.POLLIN _EVENT_WRITE = select.POLLOUT
if hasattr(select, 'epoll'):
class EpollSelector(_BaseSelectorImpl): class EpollSelector(_PollLikeSelector): """Epoll-based selector."""
def __init__(self): super().__init__() self._epoll = select.epoll() _selector_cls = select.epoll _EVENT_READ = select.EPOLLIN _EVENT_WRITE = select.EPOLLOUT
def fileno(self): return self._epoll.fileno()
def register(self, fileobj, events, data=None): key = super().register(fileobj, events, data) epoll_events = 0 if events & EVENT_READ: epoll_events |= select.EPOLLIN if events & EVENT_WRITE: epoll_events |= select.EPOLLOUT try: self._epoll.register(key.fd, epoll_events) except BaseException: super().unregister(fileobj) raise return key
def unregister(self, fileobj): key = super().unregister(fileobj) try: self._epoll.unregister(key.fd) except OSError: # This can happen if the FD was closed since it # was registered. pass return key return self._selector.fileno()
def select(self, timeout=None): if timeout is None: Expand All @@ -443,7 +437,7 @@ def select(self, timeout=None):
ready = [] try: fd_event_list = self._epoll.poll(timeout, max_ev) fd_event_list = self._selector.poll(timeout, max_ev) except InterruptedError: return ready for fd, event in fd_event_list: Expand All @@ -459,65 +453,23 @@ def select(self, timeout=None): return ready
def close(self): self._epoll.close() self._selector.close() super().close()
if hasattr(select, 'devpoll'):
class DevpollSelector(_BaseSelectorImpl): class DevpollSelector(_PollLikeSelector): """Solaris /dev/poll selector."""
def __init__(self): super().__init__() self._devpoll = select.devpoll() _selector_cls = select.devpoll _EVENT_READ = select.POLLIN _EVENT_WRITE = select.POLLOUT
def fileno(self): return self._devpoll.fileno()
def register(self, fileobj, events, data=None): key = super().register(fileobj, events, data) poll_events = 0 if events & EVENT_READ: poll_events |= select.POLLIN if events & EVENT_WRITE: poll_events |= select.POLLOUT self._devpoll.register(key.fd, poll_events) return key
def unregister(self, fileobj): key = super().unregister(fileobj) self._devpoll.unregister(key.fd) return key
def select(self, timeout=None): if timeout is None: timeout = None elif timeout <= 0: timeout = 0 else: # devpoll() has a resolution of 1 millisecond, round away from # zero to wait *at least* timeout seconds. timeout = math.ceil(timeout * 1e3) ready = [] try: fd_event_list = self._devpoll.poll(timeout) except InterruptedError: return ready for fd, event in fd_event_list: events = 0 if event & ~select.POLLIN: events |= EVENT_WRITE if event & ~select.POLLOUT: events |= EVENT_READ
key = self._key_from_fd(fd) if key: ready.append((key, events & key.events)) return ready return self._selector.fileno()
def close(self): self._devpoll.close() self._selector.close() super().close()
Expand All @@ -528,23 +480,23 @@ class KqueueSelector(_BaseSelectorImpl):
def __init__(self): super().__init__() self._kqueue = select.kqueue() self._selector = select.kqueue()
def fileno(self): return self._kqueue.fileno() return self._selector.fileno()
def register(self, fileobj, events, data=None): key = super().register(fileobj, events, data) try: if events & EVENT_READ: kev = select.kevent(key.fd, select.KQ_FILTER_READ, select.KQ_EV_ADD) self._kqueue.control([kev], 0, 0) self._selector.control([kev], 0, 0) if events & EVENT_WRITE: kev = select.kevent(key.fd, select.KQ_FILTER_WRITE, select.KQ_EV_ADD) self._kqueue.control([kev], 0, 0) except BaseException: self._selector.control([kev], 0, 0) except Exception: super().unregister(fileobj) raise return key Expand All @@ -555,7 +507,7 @@ def unregister(self, fileobj): kev = select.kevent(key.fd, select.KQ_FILTER_READ, select.KQ_EV_DELETE) try: self._kqueue.control([kev], 0, 0) self._selector.control([kev], 0, 0) except OSError: # This can happen if the FD was closed since it # was registered. Expand All @@ -564,7 +516,7 @@ def unregister(self, fileobj): kev = select.kevent(key.fd, select.KQ_FILTER_WRITE, select.KQ_EV_DELETE) try: self._kqueue.control([kev], 0, 0) self._selector.control([kev], 0, 0) except OSError: # See comment above. pass Expand All @@ -575,7 +527,7 @@ def select(self, timeout=None): max_ev = len(self._fd_to_key) ready = [] try: kev_list = self._kqueue.control(None, max_ev, timeout) kev_list = self._selector.control(None, max_ev, timeout) except InterruptedError: return ready for kev in kev_list: Expand All @@ -593,7 +545,7 @@ def select(self, timeout=None): return ready
def close(self): self._kqueue.close() self._selector.close() super().close()
Expand Down