selectors' closing behaviors completely inconsistent across selector types
Nobody has claimed this yet.
- Dominant language
- Python
- Stars
- 77.2k
- Forks
- 36k
- PR merge metrics
- PR metrics pending
Description
Several behaviors in selectors differ across implementations in major ways.
- What happens when a selector is selecting and is closed from a different thread?
- What happens when a selector is closed and
selectis called thereafter? - What error (if any) is raised if a selector cannot be used after close.
While individual select implementations can exhibit selector-type-specific behaviors, selectors provides a high-level abstraction that should behave in a consistent fashion.
Examples of inconsistent behaviors (select-after-close):
Python 3.10.4 (main, Mar 28 2022, 17:39:22) [GCC 11.2.1 20220127 (Red Hat 11.2.1-9)] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import selectors
>>> s = selectors.SelectSelector()
>>> s.close()
>>> s.select()
^CTraceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/home/arcivanov/.pyenv/versions/3.10.4/lib/python3.10/selectors.py", line 324, in select
r, w, _ = self._select(self._readers, self._writers, [], timeout)
KeyboardInterrupt
>>> s = selectors.PollSelector()
>>> s.close()
>>> s.select()
^CTraceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/home/arcivanov/.pyenv/versions/3.10.4/lib/python3.10/selectors.py", line 416, in select
fd_event_list = self._selector.poll(timeout)
KeyboardInterrupt
>>> s = selectors.EpollSelector()
>>> s.close()
>>> s.select()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/home/arcivanov/.pyenv/versions/3.10.4/lib/python3.10/selectors.py", line 469, in select
fd_event_list = self._selector.poll(timeout, max_ev)
ValueError: I/O operation on closed epoll object
Proposal:
- Closing a selector (from a different thread) while it is blocked in a select will always result in select returning immediately with no ready keys. This indicates
EOFiftimeout=Noneor is indistinguishable from timeout otherwise. See [4]. - All selectors will have a
fileno()regardless of implementation. - In all cases where selector is call-based (
select/poll) a sentinel file (os.pipe) will be used as afileno()and never returned in the ready list. - Selecting on a closed selector will result in an
OSErrorirrespective of the underlying implementation. - Analogous to
fileobject,closedproperty returnsTruewhen selector is closed.
In cases when a selector implementation is not backed by a file-based object, this will result in 2 more file handles used per selector created (either a pipe or a socketpair).
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with selectors.py and compare SelectSelector, PollSelector, and EpollSelector, focusing on close(), select(), fileno(), and closed behavior. Review the proposed cross-thread wakeup and post-close semantics, then add coverage for each selector type and verify that closed selectors raise OSError and blocked selects return as specified.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- python
- Domain
- operating-systems
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 30/100