Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

threading.local() implementation is not thread-safe in the free-threaded build #120973

Open
colesbury opened this issue Jun 24, 2024 · 1 comment
Assignees
Labels
3.13 bugs and security fixes 3.14 new features, bugs and security fixes topic-free-threading type-bug An unexpected behavior, bug, or error

Comments

@colesbury
Copy link
Contributor

colesbury commented Jun 24, 2024

Bug report

The implementation of Python thread local variables (threading.local() or _thread._local) has some thread-safety issues. The issues are particularly relevant to the free-threaded build, but some can affect the default build too.

local_clear loop over threads isn't safe

The local_clear() function is called when a thread local variable is destroyed. It loops over all threads in the interpreter and removes itself from their dictionaries.

HEAD_LOCK(runtime);
PyThreadState *tstate = PyInterpreterState_ThreadHead(interp);
HEAD_UNLOCK(runtime);
while (tstate) {
if (tstate->dict) {
if (PyDict_Pop(tstate->dict, self->key, NULL) < 0) {
// Silently ignore error
PyErr_Clear();
}
}
HEAD_LOCK(runtime);
tstate = PyThreadState_Next(tstate);
HEAD_UNLOCK(runtime);
}

This isn't thread-safe because after HEAD_UNLOCK(runtime), the stored tstate might be deleted concurrently. This can happen even in the default build with the GIL enabled because PyThreadState_Delete() doesn't require the GIL to be held. However, it's less likely to occur in practice because threading module created threads hold onto the GIL until they're deleted.

local_clear access to tstate->dict isn't thread-safe

In the free-threaded build, local_clear() may be run concurrently with some other thread's PyThreadState_Clear(). The access to another thread's tstate->dict isn't safe because it may be getting destroyed concurrently.

Linked PRs

@colesbury colesbury added type-bug An unexpected behavior, bug, or error 3.13 bugs and security fixes topic-free-threading 3.14 new features, bugs and security fixes labels Jun 24, 2024
@mpage mpage self-assigned this Jun 28, 2024
@corona10
Copy link
Member

@mpage #118490 if the linked issue is related to this issue, please take a look at both of them :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
3.13 bugs and security fixes 3.14 new features, bugs and security fixes topic-free-threading type-bug An unexpected behavior, bug, or error
Projects
None yet
Development

No branches or pull requests

3 participants