Data race on `event_tstate` in `_tkinter.c` under free-threading
Nobody has claimed this yet.
- Dominant language
- Python
- Stars
- 77.2k
- Forks
- 35.9k
- PR merge metrics
- PR metrics pending
Description
Bug report
Bug description:
event_tstate in Modules/_tkinter.c is written without synchronization in EnableEventHook() (~line 3545) and read under tcl_lock in EventHook() (~line 3507). _tkinter declares Py_MOD_GIL_NOT_USED, so the GIL no longer serializes these accesses under --disable-gil.
A torn read of event_tstate hands ENTER_PYTHON / PyEval_RestoreThread a dangling or NULL thread state.
Code
Write site (no lock):
// Modules/_tkinter.c, EnableEventHook, ~line 3545
event_tstate = tstate;
Read site (under tcl_lock only):
// Modules/_tkinter.c, EventHook, ~line 3507
Py_BEGIN_ALLOW_THREADS
if(tcl_lock) PyThread_acquire_lock(tcl_lock, 1);
tcl_tstate = event_tstate; // racy read
result = Tcl_DoOneEvent(TCL_DONT_WAIT);
tcl_tstate = NULL;
if(tcl_lock) PyThread_release_lock(tcl_lock);
...
Py_END_ALLOW_THREADS
The write in EnableEventHook happens entirely outside tcl_lock.
Suggested fix
// Write site
_Py_atomic_store_ptr(&event_tstate, tstate);
// Read site
tcl_tstate = _Py_atomic_load_ptr(&event_tstate);
CPython versions tested on:
CPython main branch
Operating systems tested on:
Linux, macOS
Linked PRs
- gh-153640
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start in Modules/_tkinter.c at EnableEventHook (~line 3545) and EventHook (~line 3507), then review the suggested atomic pointer APIs. Verify both accesses are synchronized under --disable-gil; done means the event_tstate race is removed without introducing invalid thread-state handling.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- c, python
- Domain
- backend
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Stale
- Clarity
- Clearly specified
- Newbie friendliness
- 25/100