selectors' closing behaviors completely inconsistent across selector types

未关闭
#91,433 0 条评论 0 个 reaction 已指派 0 人 在 GitHub 查看

还没有人认领这个 Issue。

评估

难度
5/5
预计耗时
一周以上
新手友好度
30/100
Issue 类型
功能
描述清晰度
基本清楚
活跃度
停滞
技术栈
python

调研方向

从 selectors.py 开始,比较 SelectSelector、PollSelector 和 EpollSelector,重点关注 close()、select()、fileno() 以及 closed 的行为。审查提议的跨线程唤醒和关闭后的语义,然后为每种 selector 类型添加覆盖,并验证已关闭的 selector 会引发 OSError,且阻塞的 select 调用会按指定方式返回。

由索引模型根据 Issue 内容生成。

描述

stdlib topic-socket

Several behaviors in selectors differ across implementations in major ways.

  1. What happens when a selector is selecting and is closed from a different thread?
  2. What happens when a selector is closed and select is called thereafter?
  3. 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:

  1. 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 EOF if timeout=None or is indistinguishable from timeout otherwise. See [4].
  2. All selectors will have a fileno() regardless of implementation.
  3. In all cases where selector is call-based (select/poll) a sentinel file (os.pipe) will be used as a fileno() and never returned in the ready list.
  4. Selecting on a closed selector will result in an OSError irrespective of the underlying implementation.
  5. Analogous tofile object, closed property returns True when 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).

主要语言
Python
星标
77.2k
派生
36k
平均合并
1 天 9 小时
30 天内合并 PR
558

贡献指南

打开贡献指南

从这里开始

  1. 先读完整个 Issue,再读项目的贡献指南。
  2. 在 Issue 下留言说明你要接手 —— 这能避免两个人做同样的事。
  3. Fork 仓库,在一个分支上完成修改。
  4. 提交 Pull Request,并在描述里引用这个 Issue 编号。

python/cpython 的其他 Issue

查看 python/cpython 的全部 Issue

相似的 Issue

更多 Python Issue

把新 issue 发到你的邮箱

精选适合新手参与的 GitHub issue 摘要。