diff options
author | Giampaolo Rodola <g.rodola@gmail.com> | 2017-06-09 20:20:41 (GMT) |
---|---|---|
committer | Victor Stinner <victor.stinner@gmail.com> | 2017-06-09 20:20:41 (GMT) |
commit | fbfaa6fd57f8dc8a3da808acb8422370fad2f27b (patch) | |
tree | 19698cdf7bc911be2a0332055abd6b6b5d5f629f /Lib/selectors.py | |
parent | 894a654a9caafb7a5bf63e1383a048041c05023b (diff) | |
download | cpython-fbfaa6fd57f8dc8a3da808acb8422370fad2f27b.zip cpython-fbfaa6fd57f8dc8a3da808acb8422370fad2f27b.tar.gz cpython-fbfaa6fd57f8dc8a3da808acb8422370fad2f27b.tar.bz2 |
bpo-30014: make poll-like selector's modify() method faster (#1030)
* #30014: make selectors.DefaultSelector.modify() faster by relying on selector's modify() method instead of un/register()ing the fd
* #30014: add unit test
* speedup poll/epoll/devpoll modify() method by using internal modify() call
* update doc
* address PR comments
* update NEWS entries
* use != instead of 'is not'
Diffstat (limited to 'Lib/selectors.py')
-rw-r--r-- | Lib/selectors.py | 30 |
1 files changed, 29 insertions, 1 deletions
diff --git a/Lib/selectors.py b/Lib/selectors.py index f29d11f..edde22c 100644 --- a/Lib/selectors.py +++ b/Lib/selectors.py @@ -252,7 +252,6 @@ class _BaseSelectorImpl(BaseSelector): return key def modify(self, fileobj, events, data=None): - # TODO: Subclasses can probably optimize this even further. try: key = self._fd_to_key[self._fileobj_lookup(fileobj)] except KeyError: @@ -342,6 +341,8 @@ class SelectSelector(_BaseSelectorImpl): class _PollLikeSelector(_BaseSelectorImpl): """Base class shared between poll, epoll and devpoll selectors.""" _selector_cls = None + _EVENT_READ = None + _EVENT_WRITE = None def __init__(self): super().__init__() @@ -371,6 +372,33 @@ class _PollLikeSelector(_BaseSelectorImpl): pass return key + def modify(self, fileobj, events, data=None): + try: + key = self._fd_to_key[self._fileobj_lookup(fileobj)] + except KeyError: + raise KeyError(f"{fileobj!r} is not registered") from None + + changed = False + if events != key.events: + selector_events = 0 + if events & EVENT_READ: + selector_events |= self._EVENT_READ + if events & EVENT_WRITE: + selector_events |= self._EVENT_WRITE + try: + self._selector.modify(key.fd, selector_events) + except Exception: + super().unregister(fileobj) + raise + changed = True + if data != key.data: + changed = True + + if changed: + key = key._replace(events=events, data=data) + self._fd_to_key[key.fd] = key + return key + def select(self, timeout=None): # This is shared between poll() and epoll(). # epoll() has a different signature and handling of timeout parameter. |