8000 gh-106751: selectors: optimize EpollSelector.select() by bdraco · Pull Request #106754 · python/cpython · GitHub
[go: up one dir, main page]

Skip to content

gh-106751: selectors: optimize EpollSelector.select() #106754

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 7 commits into from
Jul 18, 2023
Merged
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Next Next commit
Optimize EpollSelector performance
  • Loading branch information
bdraco committed Jul 14, 2023
commit 5ad3d6331147e2c24d64aa2b5e7f097b15196498
27 changes: 17 additions & 10 deletions Lib/selectors.py
Original file line number Diff line number Diff line change
Expand Up @@ -430,6 +430,9 @@ class PollSelector(_PollLikeSelector):

if hasattr(select, 'epoll'):

NOT_EPOLLIN = ~select.EPOLLIN
NOT_EPOLLOUT = ~select.EPOLLOUT

class EpollSelector(_PollLikeSelector):
"""Epoll-based selector."""
_selector_cls = select.epoll
Expand All @@ -448,27 +451,31 @@ def select(self, timeout=None):
# epoll_wait() has a resolution of 1 millisecond, round away
# from zero to wait *at least* timeout seconds.
timeout = math.ceil(timeout * 1e3) * 1e-3

# epoll_wait() expects `maxevents` to be greater than zero;
# we want to make sure that `select()` can be called when no
# FD is registered.
max_ev = max(len(self._fd_to_key), 1)
max_ev = len(self._fd_to_key) or 1

ready = []
try:
fd_event_list = self._selector.poll(timeout, max_ev)
except InterruptedError:
return ready
for fd, event in fd_event_list:
events = 0
if event & ~select.EPOLLIN:
events |= EVENT_WRITE
if event & ~select.EPOLLOUT:
events |= EVENT_READ

key = self._fd_to_key.get(fd)
fd_to_key = self._fd_to_key
for fd, event in fd_event_list:
key = fd_to_key.get(fd)
if key:
ready.append((key, events & key.events))
ready.append(
(
key,
(
(event & NOT_EPOLLIN and EVENT_WRITE)
| (event & NOT_EPOLLOUT and EVENT_READ)
)
& key.events
)
)
return ready

def close(self):
Expand Down
0