Skip to content
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

KqueueSelector miscounts max events #110038

Closed
sorcio opened this issue Sep 28, 2023 · 2 comments
Closed

KqueueSelector miscounts max events #110038

sorcio opened this issue Sep 28, 2023 · 2 comments
Labels
OS-freebsd type-bug An unexpected behavior, bug, or error

Comments

@sorcio
Copy link
Contributor

sorcio commented Sep 28, 2023

Bug report

Bug description:

KqueueSelector.select() may not get all events if a fd is registered for both read and write.

kqueue requires to register two filters, one for read and one for write. But KqueueSelector.select() calls kqueue.control() counting the number of registered fds, not the filters. As a result a single call to select() won't return all the available events.

>>> import socket, selectors
>>> sel = selectors.KqueueSelector()
>>> s1, s2 = socket.socketpair()
>>> sel.register(s1, selectors.EVENT_READ | selectors.EVENT_WRITE)
SelectorKey(fileobj=<socket.socket fd=4, family=1, type=1, proto=0>, fd=4, events=3, data=None)
>>> s2.send(b"foo")
3
>>> sel.select()
[(SelectorKey(fileobj=<socket.socket fd=4, family=1, type=1, proto=0>, fd=4, events=3, data=None), 2)]
>>> sel.select()
[(SelectorKey(fileobj=<socket.socket fd=4, family=1, type=1, proto=0>, fd=4, events=3, data=None), 1)]

(Note that the two events are only visible on two subsequent selects)

For users like asyncio, this might mean missing a loop cycle or more (depending on number of registered readers/writers and ready events) before an event is seen. I previously said that this might cause deadlocks but I could not produce an example where a read/write event is never seen.

CPython versions tested on:

3.11, 3.12, CPython main branch

Operating systems tested on:

macOS, Other

Linked PRs

@sorcio sorcio added the type-bug An unexpected behavior, bug, or error label Sep 28, 2023
sorcio added a commit to sorcio/cpython that referenced this issue Sep 28, 2023
sorcio added a commit to sorcio/cpython that referenced this issue Sep 28, 2023
…ts (pythonGH-110039).

(cherry picked from commit b14f0ab)

Co-authored-by: Davide Rizzo <sorcio@gmail.com>
sorcio added a commit to sorcio/cpython that referenced this issue Sep 28, 2023
…ts (pythonGH-110039).

(cherry picked from commit b14f0ab)

Co-authored-by: Davide Rizzo <sorcio@gmail.com>
vstinner pushed a commit that referenced this issue Sep 28, 2023
…-110039) (#110044)

[3.11] gh-110038: KqueueSelector must count all read/write events (GH-110039).
(cherry picked from commit b14f0ab)
Yhg1s pushed a commit that referenced this issue Oct 2, 2023
…-110039) (#110043)

[3.12] gh-110038: KqueueSelector must count all read/write events (GH-110039).
(cherry picked from commit b14f0ab)
@hugovk
Copy link
Member

hugovk commented Nov 9, 2023

Thanks for the issue and PRs!

@hugovk hugovk closed this as completed Nov 9, 2023
@vstinner
Copy link
Member

vstinner commented Nov 9, 2023

Thanks for the fix @sorcio.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
OS-freebsd type-bug An unexpected behavior, bug, or error
Projects
None yet
Development

No branches or pull requests

3 participants