Skip to content

Commit 6efd78d

Browse files
[3.14] pythongh-137093: Fix race condition in test_embed.test_bpo20891 (pythonGH-137094) (python#140524)
Use a `PyEvent` instead of a lock to fix a race on the free-threaded build. (cherry picked from commit 9b451fb) Co-authored-by: Peter Bierma <[email protected]>
1 parent 8285bc7 commit 6efd78d

File tree

1 file changed

+6
-17
lines changed

1 file changed

+6
-17
lines changed

Programs/_testembed.c

Lines changed: 6 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -413,9 +413,9 @@ static int test_pre_initialization_sys_options(void)
413413

414414

415415
/* bpo-20891: Avoid race condition when initialising the GIL */
416-
static void bpo20891_thread(void *lockp)
416+
static void bpo20891_thread(void *eventp)
417417
{
418-
PyThread_type_lock lock = *((PyThread_type_lock*)lockp);
418+
PyEvent *event = (PyEvent *)eventp;
419419

420420
PyGILState_STATE state = PyGILState_Ensure();
421421
if (!PyGILState_Check()) {
@@ -424,8 +424,7 @@ static void bpo20891_thread(void *lockp)
424424
}
425425

426426
PyGILState_Release(state);
427-
428-
PyThread_release_lock(lock);
427+
_PyEvent_Notify(event);
429428
}
430429

431430
static int test_bpo20891(void)
@@ -435,27 +434,17 @@ static int test_bpo20891(void)
435434

436435
/* bpo-20891: Calling PyGILState_Ensure in a non-Python thread must not
437436
crash. */
438-
PyThread_type_lock lock = PyThread_allocate_lock();
439-
if (!lock) {
440-
error("PyThread_allocate_lock failed!");
441-
return 1;
442-
}
443437

444438
_testembed_Py_InitializeFromConfig();
439+
PyEvent event = {0};
445440

446-
unsigned long thrd = PyThread_start_new_thread(bpo20891_thread, &lock);
441+
unsigned long thrd = PyThread_start_new_thread(bpo20891_thread, &event);
447442
if (thrd == PYTHREAD_INVALID_THREAD_ID) {
448443
error("PyThread_start_new_thread failed!");
449444
return 1;
450445
}
451-
PyThread_acquire_lock(lock, WAIT_LOCK);
452-
453-
Py_BEGIN_ALLOW_THREADS
454-
/* wait until the thread exit */
455-
PyThread_acquire_lock(lock, WAIT_LOCK);
456-
Py_END_ALLOW_THREADS
457446

458-
PyThread_free_lock(lock);
447+
PyEvent_Wait(&event);
459448

460449
Py_Finalize();
461450

0 commit comments

Comments
 (0)