8000 gh-117300: Use stop the world to make `sys._current_frames` and `sys.… · python/cpython@01bd74e · GitHub
[go: up one dir, main page]

Skip to content

Commit 01bd74e

Browse files
authored
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.
1 parent 94c9742 commit 01bd74e

File tree

2 files changed

+6
-1
lines changed

2 files changed

+6
-1
lines changed

Lib/test/test_sys.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -562,7 +562,8 @@ def g456():
562562
# And the next record must be for g456().
563563
filename, lineno, funcname, sourceline = stack[i+1]
564564
self.assertEqual(funcname, "g456")
565-
self.assertTrue(sourceline.startswith("if leave_g.wait("))
565+
self.assertTrue((sourceline.startswith("if leave_g.wait(") or
566+
sourceline.startswith("g_raised.set()")))
566567
finally:
567568
# Reap the spawned thread.
568569
leave_g.set()

Python/pystate.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2408,6 +2408,7 @@ _PyThread_CurrentFrames(void)
24082408
* Because these lists can mutate even when the GIL is held, we
24092409
* need to grab head_mutex for the duration.
24102410
*/
2411+
_PyEval_StopTheWorldAll(runtime);
24112412
HEAD_LOCK(runtime);
24122413
PyInterpreterState *i;
24132414
for (i = runtime->interpreters.head; i != NULL; i = i->next) {
@@ -2441,6 +2442,7 @@ _PyThread_CurrentFrames(void)
24412442

24422443
done:
24432444
HEAD_UNLOCK(runtime);
2445+
_PyEval_StartTheWorldAll(runtime);
24442446
return result;
24452447
}
24462448

@@ -2472,6 +2474,7 @@ _PyThread_CurrentExceptions(void)
24722474
* Because these lists can mutate even when the GIL is held, we
24732475
* need to grab head_mutex for the duration.
24742476
*/
2477+
_PyEval_StopTheWorldAll(runtime);
24752478
HEAD_LOCK(runtime);
24762479
PyInterpreterState *i;
24772480
for (i = runtime->interpreters.head; i != NULL; i = i->next) {
@@ -2504,6 +2507,7 @@ _PyThread_CurrentExceptions(void)
25042507

25052508
done:
25062509
HEAD_UNLOCK(runtime);
2510+
_PyEval_StartTheWorldAll(runtime);
25072511
return result;
25082512
}
25092513

0 commit comments

Comments
 (0)
0