Skip to content

gh-152754: Fix crash when an os.scandir iterator is shared between threads - #153462

Merged
nascheme merged 10 commits into
python:mainfrom
nascheme:gh-152754-os-race-mutex
Aug 21, 2026
Merged

gh-152754: Fix crash when an os.scandir iterator is shared between threads#153462
nascheme merged 10 commits into
python:mainfrom
nascheme:gh-152754-os-race-mutex

Conversation

@nascheme

@nascheme nascheme commented Jul 9, 2026

Copy link
Copy Markdown
Member

The issue was a race between ScandirIterator_iternext() and ScandirIterator.close(): one thread could be inside readdir() or FindNextFileW() while another closed the underlying directory stream or Windows handle.

Changes

  • Add a PyMutex and atomic closed state to ScandirIterator in all builds.
  • Serialize access to the native directory stream or handle.
  • Make close() mark the iterator closed immediately without waiting for an in-progress directory read. The reading thread performs the native close afterward when necessary.
  • Copy native directory-entry data while holding the mutex, then create Python objects and report errors after releasing it.
  • Keep Py_BEGIN_ALLOW_THREADS around readdir(), FindNextFileW(), closedir(), and FindClose().
  • Avoid incorrectly emitting ResourceWarning when opening the directory fails.
  • Add regression tests for concurrent iteration, iteration racing with close(), and failed iterator creation.
  • Document the behavior of sharing a scandir() iterator between threads.

Threading semantics

Sharing an os.scandir() iterator between threads will no longer corrupt the iterator or crash. Concurrent calls may consume entries in any order, so which thread receives each entry remains unspecified. Calling close() while another thread is iterating marks the iterator closed immediately and ends iteration early.

A PyMutex is used rather than a critical section because the protection must remain active across Py_BEGIN_ALLOW_THREADS while the native directory operation runs without the GIL.

…een threads

Co-authored-by: Neil Schemenauer <nas-github@arctrix.com>
Comment thread Modules/posixmodule.c Outdated
@read-the-docs-community

read-the-docs-community Bot commented Aug 12, 2026

Copy link
Copy Markdown

@nascheme
nascheme marked this pull request as ready for review August 13, 2026 00:39
@nascheme

Copy link
Copy Markdown
Member Author

Note, I revised this PR to no longer try to be thread-safe with multiple threads using the same iterator. That seems a pretty unlikely usage scenario. Instead, this avoids crashing and/or memory corruption.

Comment thread Modules/posixmodule.c Outdated
@nascheme
nascheme merged commit 999a046 into python:main Aug 21, 2026
58 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants