mirror of
https://github.com/python/cpython.git
synced 2025-08-26 11:45:20 +00:00
gh-117300: Use stop the world to make sys._current_frames
and sys._current_exceptions
thread-safe. (#117301)
This adds a stop the world pause to make the two functions thread-safe when the GIL is disabled in the free-threaded build. Additionally, the main test thread may call `sys._current_exceptions()` as soon as `g_raised.set()` is called. The background thread may not yet reach the `leave_g.wait()` line.
This commit is contained in:
parent
94c97423a9
commit
01bd74eadb
2 changed files with 6 additions and 1 deletions
|
@ -562,7 +562,8 @@ class SysModuleTest(unittest.TestCase):
|
||||||
# And the next record must be for g456().
|
# And the next record must be for g456().
|
||||||
filename, lineno, funcname, sourceline = stack[i+1]
|
filename, lineno, funcname, sourceline = stack[i+1]
|
||||||
self.assertEqual(funcname, "g456")
|
self.assertEqual(funcname, "g456")
|
||||||
self.assertTrue(sourceline.startswith("if leave_g.wait("))
|
self.assertTrue((sourceline.startswith("if leave_g.wait(") or
|
||||||
|
sourceline.startswith("g_raised.set()")))
|
||||||
finally:
|
finally:
|
||||||
# Reap the spawned thread.
|
# Reap the spawned thread.
|
||||||
leave_g.set()
|
leave_g.set()
|
||||||
|
|
|
@ -2408,6 +2408,7 @@ _PyThread_CurrentFrames(void)
|
||||||
* Because these lists can mutate even when the GIL is held, we
|
* Because these lists can mutate even when the GIL is held, we
|
||||||
* need to grab head_mutex for the duration.
|
* need to grab head_mutex for the duration.
|
||||||
*/
|
*/
|
||||||
|
_PyEval_StopTheWorldAll(runtime);
|
||||||
HEAD_LOCK(runtime);
|
HEAD_LOCK(runtime);
|
||||||
PyInterpreterState *i;
|
PyInterpreterState *i;
|
||||||
for (i = runtime->interpreters.head; i != NULL; i = i->next) {
|
for (i = runtime->interpreters.head; i != NULL; i = i->next) {
|
||||||
|
@ -2441,6 +2442,7 @@ fail:
|
||||||
|
|
||||||
done:
|
done:
|
||||||
HEAD_UNLOCK(runtime);
|
HEAD_UNLOCK(runtime);
|
||||||
|
_PyEval_StartTheWorldAll(runtime);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2472,6 +2474,7 @@ _PyThread_CurrentExceptions(void)
|
||||||
* Because these lists can mutate even when the GIL is held, we
|
* Because these lists can mutate even when the GIL is held, we
|
||||||
* need to grab head_mutex for the duration.
|
* need to grab head_mutex for the duration.
|
||||||
*/
|
*/
|
||||||
|
_PyEval_StopTheWorldAll(runtime);
|
||||||
HEAD_LOCK(runtime);
|
HEAD_LOCK(runtime);
|
||||||
PyInterpreterState *i;
|
PyInterpreterState *i;
|
||||||
for (i = runtime->interpreters.head; i != NULL; i = i->next) {
|
for (i = runtime->interpreters.head; i != NULL; i = i->next) {
|
||||||
|
@ -2504,6 +2507,7 @@ fail:
|
||||||
|
|
||||||
done:
|
done:
|
||||||
HEAD_UNLOCK(runtime);
|
HEAD_UNLOCK(runtime);
|
||||||
|
_PyEval_StartTheWorldAll(runtime);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue