You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
make memoryview thread safe in free-threading #127716
A concrete, crashing reproducer for the "concurrent releasing" part of this issue. On a free-threaded build, several threads calling memoryview.release() on views of one shared buffer (interleaved with reads of a view) underflow the non-atomic export counters and abort.
On a free-threaded debug build (PYTHON_GIL=0) this aborts on essentially every run. The exact assertion that fires depends on the build/scheduling — both are the same root cause, a non-atomic export counter driven below its invariant by concurrent release():
Debug build with ASan — the memoryview's own mbuf->exports:
the release path double-decrements the exporter's export count (also non-atomic), so it goes negative.
Both reproduce 5/5 here. Under TSan the same race shows up as data-race stanzas pairing the release side against the read side, e.g. _memory_release / mbuf_release vs memory_readonly_get / memory_item / memory_subscript — and the read of a concurrently-released view is also a use-after-release angle.
This is the release side of the exports counter, which looks still-open under this issue — distinct from the memoryview.hex exports race that was fixed (gh-149858 / item 132 of #149816) and the earlier ->exports fix in gh-127085 (#127412) that this issue is the follow-up to.
Found with fusil's --tsan mode; reduced and drafted with AI assistance (Claude Code), verified by hand on free-threaded debug / ASan / TSan builds of main (3.16.0a0).
@devdanzin Hi, I submitted a PR #154770 trying to fix the issue you mentioned. I think self->flags need to be protected by atomic operation, then only one thread would enter the release path
Activity
picnixz commentedon Dec 7, 2024
Do you think it should be a feature (main only) or a bug fix (3.13+)?
kumaraditya303 commentedon Dec 7, 2024
For now I'll target main, if it doesn't need too many changes it may be backported.
picnixz commentedon Dec 7, 2024
Ok. I'll apply the labels after we decided whether we should backport it or not.
ZeroIntensity commentedon Dec 7, 2024
FWIW, we typically do backport thread safety fixes to 3.13. We should probably merge gh-127412 before putting up anything new to prevent conflicts.
[-]make memoryview thread safe in free-theading[/-][+]make memoryview thread safe in free-threading[/+]devdanzin commentedon Jul 25, 2026
A concrete, crashing reproducer for the "concurrent releasing" part of this issue. On a free-threaded build, several threads calling
memoryview.release()on views of one shared buffer (interleaved with reads of a view) underflow the non-atomic export counters and abort.On a free-threaded debug build (
PYTHON_GIL=0) this aborts on essentially every run. The exact assertion that fires depends on the build/scheduling — both are the same root cause, a non-atomic export counter driven below its invariant by concurrentrelease():Debug build with ASan — the memoryview's own
mbuf->exports:_memory_release(memoryobject.c:1115) decrementsself->mbuf->exportsnon-atomically, soconcurrent releases drive it to/below zero.
Plain debug build (no ASan) — the exporter bytearray's
ob_exports:the release path double-decrements the exporter's export count (also non-atomic), so it goes negative.
Both reproduce 5/5 here. Under TSan the same race shows up as data-race stanzas pairing the release side against the read side, e.g.
_memory_release/mbuf_releasevsmemory_readonly_get/memory_item/memory_subscript— and the read of a concurrently-released view is also a use-after-release angle.This is the release side of the exports counter, which looks still-open under this issue — distinct from the
memoryview.hexexports race that was fixed (gh-149858 / item 132 of #149816) and the earlier->exportsfix in gh-127085 (#127412) that this issue is the follow-up to.Found with fusil's
--tsanmode; reduced and drafted with AI assistance (Claude Code), verified by hand on free-threaded debug / ASan / TSan builds ofmain(3.16.0a0).pythongh-127716: Fix data race in `memoryview.release()`
weixlu commentedon Jul 27, 2026
@devdanzin Hi, I submitted a PR #154770 trying to fix the issue you mentioned. I think
self->flagsneed to be protected by atomic operation, then only one thread would enter the release pathpythongh-127716: make memoryview thread-safe
pythongh-127716: make memoryview thread-safe
Merge remote-tracking branch 'origin/main' into pythongh-127716-memor…
Merge remote-tracking branch 'origin/main' into pythongh-127716-memor…
Merge remote-tracking branch 'origin/main' into pythongh-127716-memor…