diff options
| author | Sam Gross <colesbury@gmail.com> | 2024-04-30 19:01:28 (GMT) |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2024-04-30 19:01:28 (GMT) |
| commit | b2c3b70c7102197e4505e6cd69722dc508527d22 (patch) | |
| tree | 6b910d740f1e3d8d3af38a487d787b3267ebff68 /Python | |
| parent | 4a1cf66c5c0afa36d7a51d5f9d3874cda10df79c (diff) | |
| download | cpython-b2c3b70c7102197e4505e6cd69722dc508527d22.zip cpython-b2c3b70c7102197e4505e6cd69722dc508527d22.tar.gz cpython-b2c3b70c7102197e4505e6cd69722dc508527d22.tar.bz2 | |
gh-118332: Fix deadlock involving stop the world (#118412)
Avoid detaching thread state when stopping the world. When re-attaching
the thread state, the thread would attempt to resume the top-most
critical section, which might now be held by a thread paused for our
stop-the-world request.
Diffstat (limited to 'Python')
| -rw-r--r-- | Python/lock.c | 6 | ||||
| -rw-r--r-- | Python/pystate.c | 3 |
2 files changed, 5 insertions, 4 deletions
diff --git a/Python/lock.c b/Python/lock.c index 91c66df..5ed95fc 100644 --- a/Python/lock.c +++ b/Python/lock.c @@ -277,12 +277,12 @@ _PyEvent_Notify(PyEvent *evt) void PyEvent_Wait(PyEvent *evt) { - while (!PyEvent_WaitTimed(evt, -1)) + while (!PyEvent_WaitTimed(evt, -1, /*detach=*/1)) ; } int -PyEvent_WaitTimed(PyEvent *evt, PyTime_t timeout_ns) +PyEvent_WaitTimed(PyEvent *evt, PyTime_t timeout_ns, int detach) { for (;;) { uint8_t v = _Py_atomic_load_uint8(&evt->v); @@ -298,7 +298,7 @@ PyEvent_WaitTimed(PyEvent *evt, PyTime_t timeout_ns) uint8_t expected = _Py_HAS_PARKED; (void) _PyParkingLot_Park(&evt->v, &expected, sizeof(evt->v), - timeout_ns, NULL, 1); + timeout_ns, NULL, detach); return _Py_atomic_load_uint8(&evt->v) == _Py_LOCKED; } diff --git a/Python/pystate.c b/Python/pystate.c index 78b39c9..9d7b73b 100644 --- a/Python/pystate.c +++ b/Python/pystate.c @@ -2238,7 +2238,8 @@ stop_the_world(struct _stoptheworld_state *stw) } PyTime_t wait_ns = 1000*1000; // 1ms (arbitrary, may need tuning) - if (PyEvent_WaitTimed(&stw->stop_event, wait_ns)) { + int detach = 0; + if (PyEvent_WaitTimed(&stw->stop_event, wait_ns, detach)) { assert(stw->thread_countdown == 0); break; } |
