mirror of
https://github.com/python/cpython.git
synced 2025-10-09 08:31:26 +00:00
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'
This commit is contained in:
parent
894a654a9c
commit
fbfaa6fd57
4 changed files with 62 additions and 1 deletions
|
@ -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.
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue