-
-
Notifications
You must be signed in to change notification settings - Fork 32.4k
Open
Labels
interpreter-core(Objects, Python, Grammar, and Parser dirs)(Objects, Python, Grammar, and Parser dirs)topic-free-threadingtype-bugAn unexpected behavior, bug, or errorAn unexpected behavior, bug, or error
Description
Bug report
Bug description:
The enumerate object (and also the itertools.pairwise
since #118219) re-uses tuples when possible. It does this by checking the reference count to be 1:
// from enum_next in enumobject.c
if (Py_REFCNT(result) == 1) {
Py_INCREF(result);
old_index = PyTuple_GET_ITEM(result, 0);
old_item = PyTuple_GET_ITEM(result, 1);
PyTuple_SET_ITEM(result, 0, next_index);
PyTuple_SET_ITEM(result, 1, next_item);
Py_DECREF(old_index);
Py_DECREF(old_item);
....
The refcount check and increment are not atomic, so in the free-threading build multiple threads can end up operating on the result
object. It is possible that one thread already sets an item in the tuple, and another thread decrefs the item believing it is still an old item.
In the nogil reference implementation (https://github.com/colesbury/nogil) no changes are made to address this. So maybe the issue cannot occur?
In #120591 this problem is addressed with a lock, which might be too much overhead (see the discussion in #120496)
CPython versions tested on:
CPython main branch
Operating systems tested on:
Windows
Linked PRs
Metadata
Metadata
Assignees
Labels
interpreter-core(Objects, Python, Grammar, and Parser dirs)(Objects, Python, Grammar, and Parser dirs)topic-free-threadingtype-bugAn unexpected behavior, bug, or errorAn unexpected behavior, bug, or error