Skip to content

Commit aaf3cef

Browse files
committed
Finish migration to the new API.
1 parent a9da6b6 commit aaf3cef

File tree

6 files changed

+242
-254
lines changed

6 files changed

+242
-254
lines changed

Include/cpython/pystate.h

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -282,9 +282,11 @@ PyAPI_FUNC(void) _PyInterpreterState_SetEvalFrameFunc(
282282
PyInterpreterState *interp,
283283
_PyFrameEvalFunction eval_frame);
284284

285-
/* Strong interpreter references */
285+
/* Interpreter locks */
286286

287287
typedef uintptr_t PyInterpreterLock;
288+
typedef uintptr_t PyInterpreterView;
289+
288290

289291
PyAPI_FUNC(PyInterpreterLock) PyInterpreterLock_FromCurrent(void);
290292
PyAPI_FUNC(PyInterpreterLock) PyInterpreterLock_Copy(PyInterpreterLock lock);
@@ -294,7 +296,7 @@ PyAPI_FUNC(PyInterpreterLock) PyInterpreterLock_FromView(PyInterpreterView view)
294296

295297
#define PyInterpreterLock_Release(lock) do { \
296298
PyInterpreterLock_Release(lock); \
297-
ref = 0; \
299+
lock = 0; \
298300
} while (0)
299301

300302
/* Interpreter views */
@@ -304,8 +306,6 @@ typedef struct _PyInterpreterView {
304306
Py_ssize_t refcount;
305307
} _PyInterpreterView;
306308

307-
typedef uintptr_t PyInterpreterView;
308-
309309
PyAPI_FUNC(PyInterpreterView) PyInterpreterView_FromCurrent(void);
310310
PyAPI_FUNC(PyInterpreterView) PyInterpreterView_Copy(PyInterpreterView view);
311311
PyAPI_FUNC(void) PyInterpreterView_Close(PyInterpreterView view);
@@ -314,7 +314,7 @@ PyAPI_FUNC(PyInterpreterView) PyUnstable_InterpreterView_FromDefault(void);
314314

315315
#define PyInterpreterView_Close(view) do { \
316316
PyInterpreterView_Close(view); \
317-
ref = 0; \
317+
view = 0; \
318318
} while (0)
319319

320320

Modules/_testcapimodule.c

Lines changed: 48 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -2562,24 +2562,16 @@ toggle_reftrace_printer(PyObject *ob, PyObject *arg)
25622562
Py_RETURN_NONE;
25632563
}
25642564

2565-
static PyInterpreterLock
2566-
get_strong_ref(void)
2567-
{
2568-
PyInterpreterLock ref;
2569-
if (PyInterpreterLock_FromCurrent(&ref) < 0) {
2570-
Py_FatalError("strong reference should not have failed");
2571-
}
2572-
return ref;
2573-
}
2574-
25752565
static void
2576-
test_interp_ref_common(void)
2566+
test_interp_locks_common(void)
25772567
{
25782568
PyInterpreterState *interp = PyInterpreterState_Get();
2579-
PyInterpreterLock ref = get_strong_ref();
2569+
PyInterpreterLock ref = PyInterpreterLock_FromCurrent();
2570+
assert(ref != 0);
25802571
assert(PyInterpreterLock_GetInterpreter(ref) == interp);
25812572

25822573
PyInterpreterLock ref_2 = PyInterpreterLock_Copy(ref);
2574+
assert(ref_2 != 0);
25832575
assert(PyInterpreterLock_GetInterpreter(ref_2) == interp);
25842576

25852577
// We can close the references in any order
@@ -2588,15 +2580,15 @@ test_interp_ref_common(void)
25882580
}
25892581

25902582
static PyObject *
2591-
test_interpreter_refs(PyObject *self, PyObject *unused)
2583+
test_interpreter_locks(PyObject *self, PyObject *unused)
25922584
{
25932585
// Test the main interpreter
2594-
test_interp_ref_common();
2586+
test_interp_locks_common();
25952587

25962588
// Test a (legacy) subinterpreter
25972589
PyThreadState *save_tstate = PyThreadState_Swap(NULL);
25982590
PyThreadState *interp_tstate = Py_NewInterpreter();
2599-
test_interp_ref_common();
2591+
test_interp_locks_common();
26002592
Py_EndInterpreter(interp_tstate);
26012593

26022594
// Test an isolated subinterpreter
@@ -2612,7 +2604,7 @@ test_interpreter_refs(PyObject *self, PyObject *unused)
26122604
return NULL;
26132605
}
26142606

2615-
test_interp_ref_common();
2607+
test_interp_locks_common();
26162608
Py_EndInterpreter(isolated_interp_tstate);
26172609
PyThreadState_Swap(save_tstate);
26182610
Py_RETURN_NONE;
@@ -2621,21 +2613,25 @@ test_interpreter_refs(PyObject *self, PyObject *unused)
26212613
static PyObject *
26222614
test_thread_state_ensure_nested(PyObject *self, PyObject *unused)
26232615
{
2624-
PyInterpreterLock ref = get_strong_ref();
2616+
PyInterpreterLock lock = PyInterpreterLock_FromCurrent();
2617+
if (lock == 0) {
2618+
return NULL;
2619+
}
26252620
PyThreadState *save_tstate = PyThreadState_Swap(NULL);
26262621
assert(PyGILState_GetThisThreadState() == save_tstate);
2627-
PyThreadView refs[10];
2622+
PyThreadView thread_views[10];
26282623

26292624
for (int i = 0; i < 10; ++i) {
26302625
// Test reactivation of the detached tstate.
2631-
if (PyThreadState_Ensure(ref, &refs[i]) < 0) {
2632-
PyInterpreterLock_Release(ref);
2626+
thread_views[i] = PyThreadState_Ensure(lock);
2627+
if (thread_views[i] == 0) {
2628+
PyInterpreterLock_Release(lock);
26332629
return PyErr_NoMemory();
26342630
}
26352631

26362632
// No new thread state should've been created.
26372633
assert(PyThreadState_Get() == save_tstate);
2638-
PyThreadState_Release(refs[i]);
2634+
PyThreadState_Release(thread_views[i]);
26392635
}
26402636

26412637
assert(PyThreadState_GetUnchecked() == NULL);
@@ -2644,10 +2640,11 @@ test_thread_state_ensure_nested(PyObject *self, PyObject *unused)
26442640
// If the (detached) gilstate matches the interpreter, then it shouldn't
26452641
// create a new thread state.
26462642
for (int i = 0; i < 10; ++i) {
2647-
if (PyThreadState_Ensure(ref, &refs[i]) < 0) {
2643+
thread_views[i] = PyThreadState_Ensure(lock);
2644+
if (thread_views[i] == 0) {
26482645
// This will technically leak other thread states, but it doesn't
26492646
// matter because this is a test.
2650-
PyInterpreterLock_Release(ref);
2647+
PyInterpreterLock_Release(lock);
26512648
return PyErr_NoMemory();
26522649
}
26532650

@@ -2656,23 +2653,23 @@ test_thread_state_ensure_nested(PyObject *self, PyObject *unused)
26562653

26572654
for (int i = 0; i < 10; ++i) {
26582655
assert(PyThreadState_Get() == save_tstate);
2659-
PyThreadState_Release(refs[i]);
2656+
PyThreadState_Release(thread_views[i]);
26602657
}
26612658

26622659
assert(PyThreadState_GetUnchecked() == NULL);
2663-
PyInterpreterLock_Release(ref);
2660+
PyInterpreterLock_Release(lock);
26642661
PyThreadState_Swap(save_tstate);
26652662
Py_RETURN_NONE;
26662663
}
26672664

26682665
static PyObject *
26692666
test_thread_state_ensure_crossinterp(PyObject *self, PyObject *unused)
26702667
{
2671-
PyInterpreterLock ref = get_strong_ref();
2668+
PyInterpreterLock lock = PyInterpreterLock_FromCurrent();
26722669
PyThreadState *save_tstate = PyThreadState_Swap(NULL);
26732670
PyThreadState *interp_tstate = Py_NewInterpreter();
26742671
if (interp_tstate == NULL) {
2675-
PyInterpreterLock_Release(ref);
2672+
PyInterpreterLock_Release(lock);
26762673
return PyErr_NoMemory();
26772674
}
26782675

@@ -2689,79 +2686,69 @@ test_thread_state_ensure_crossinterp(PyObject *self, PyObject *unused)
26892686
interp = interpreters.create()
26902687
interp.exec(some_func)
26912688
*/
2692-
PyThreadView thread_ref;
2693-
PyThreadView other_thread_ref;
2694-
if (PyThreadState_Ensure(ref, &thread_ref) < 0) {
2695-
PyInterpreterLock_Release(ref);
2689+
PyThreadView thread_view = PyThreadState_Ensure(lock);
2690+
if (thread_view == 0) {
2691+
PyInterpreterLock_Release(lock);
26962692
return PyErr_NoMemory();
26972693
}
26982694

26992695
PyThreadState *ensured_tstate = PyThreadState_Get();
27002696
assert(ensured_tstate != save_tstate);
2701-
assert(PyInterpreterState_Get() == PyInterpreterLock_GetInterpreter(ref));
2697+
assert(PyInterpreterState_Get() == PyInterpreterLock_GetInterpreter(lock));
27022698
assert(PyGILState_GetThisThreadState() == ensured_tstate);
27032699

27042700
// Now though, we should reactivate the thread state
2705-
if (PyThreadState_Ensure(ref, &other_thread_ref) < 0) {
2706-
PyInterpreterLock_Release(ref);
2701+
PyThreadView other_thread_view = PyThreadState_Ensure(lock);
2702+
if (other_thread_view == 0) {
2703+
PyThreadState_Release(thread_view);
2704+
PyInterpreterLock_Release(lock);
27072705
return PyErr_NoMemory();
27082706
}
27092707

27102708
assert(PyThreadState_Get() == ensured_tstate);
2711-
PyThreadState_Release(other_thread_ref);
2709+
PyThreadState_Release(other_thread_view);
27122710

27132711
// Ensure that we're restoring the prior thread state
2714-
PyThreadState_Release(thread_ref);
2712+
PyThreadState_Release(thread_view);
27152713
assert(PyThreadState_Get() == interp_tstate);
27162714
assert(PyGILState_GetThisThreadState() == interp_tstate);
27172715

27182716
PyThreadState_Swap(interp_tstate);
27192717
Py_EndInterpreter(interp_tstate);
27202718

2721-
PyInterpreterLock_Release(ref);
2719+
PyInterpreterLock_Release(lock);
27222720
PyThreadState_Swap(save_tstate);
27232721
Py_RETURN_NONE;
27242722
}
27252723

27262724
static PyObject *
2727-
test_weak_interpreter_ref_after_shutdown(PyObject *self, PyObject *unused)
2725+
test_interp_view_after_shutdown(PyObject *self, PyObject *unused)
27282726
{
27292727
PyThreadState *save_tstate = PyThreadState_Swap(NULL);
2730-
PyInterpreterView wref;
27312728
PyThreadState *interp_tstate = Py_NewInterpreter();
27322729
if (interp_tstate == NULL) {
27332730
return PyErr_NoMemory();
27342731
}
27352732

2736-
int res = PyInterpreterView_FromCurrent(&wref);
2737-
(void)res;
2738-
assert(res == 0);
2733+
PyInterpreterView view = PyInterpreterView_FromCurrent();
2734+
if (view == 0) {
2735+
return PyErr_NoMemory();
2736+
}
27392737

2740-
// As a sanity check, ensure that the weakref actually works
2741-
PyInterpreterLock ref;
2742-
res = PyInterpreterLock_FromView(wref, &ref);
2743-
assert(res == 0);
2744-
PyInterpreterLock_Release(ref);
2738+
// As a sanity check, ensure that the view actually works
2739+
PyInterpreterLock lock = PyInterpreterLock_FromView(view);
2740+
PyInterpreterLock_Release(lock);
27452741

2746-
// Now, destroy the interpreter and try to acquire a weak reference.
2742+
// Now, destroy the interpreter and try to acquire a lock from a view.
27472743
// It should fail.
27482744
Py_EndInterpreter(interp_tstate);
2749-
res = PyInterpreterLock_FromView(wref, &ref);
2750-
assert(res == -1);
2745+
lock = PyInterpreterLock_FromView(view);
2746+
assert(lock == 0);
27512747

27522748
PyThreadState_Swap(save_tstate);
27532749
Py_RETURN_NONE;
27542750
}
27552751

2756-
static PyObject *
2757-
foo(PyObject *self, PyObject *foo)
2758-
{
2759-
PyInterpreterLock ref;
2760-
PyInterpreterLock_FromCurrent(&ref);
2761-
PyInterpreterLock_Release(ref);
2762-
Py_RETURN_NONE;
2763-
}
2764-
27652752
static PyMethodDef TestMethods[] = {
27662753
{"set_errno", set_errno, METH_VARARGS},
27672754
{"test_config", test_config, METH_NOARGS},
@@ -2856,11 +2843,10 @@ static PyMethodDef TestMethods[] = {
28562843
{"test_atexit", test_atexit, METH_NOARGS},
28572844
{"code_offset_to_line", _PyCFunction_CAST(code_offset_to_line), METH_FASTCALL},
28582845
{"toggle_reftrace_printer", toggle_reftrace_printer, METH_O},
2859-
{"test_interpreter_refs", test_interpreter_refs, METH_NOARGS},
2846+
{"test_interpreter_lock", test_interpreter_locks, METH_NOARGS},
28602847
{"test_thread_state_ensure_nested", test_thread_state_ensure_nested, METH_NOARGS},
28612848
{"test_thread_state_ensure_crossinterp", test_thread_state_ensure_crossinterp, METH_NOARGS},
2862-
{"test_weak_interpreter_ref_after_shutdown", test_weak_interpreter_ref_after_shutdown, METH_NOARGS},
2863-
{"foo", foo, METH_NOARGS},
2849+
{"test_interp_view_after_shutdown", test_interp_view_after_shutdown, METH_NOARGS},
28642850
{NULL, NULL} /* sentinel */
28652851
};
28662852

Modules/_testinternalcapi.c

Lines changed: 24 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -2418,59 +2418,57 @@ set_vectorcall_nop(PyObject *self, PyObject *func)
24182418
Py_RETURN_NONE;
24192419
}
24202420

2421-
#define NUM_REFS 100
2421+
#define NUM_LOCKS 100
24222422

24232423
static PyObject *
2424-
test_interp_refcount(PyObject *self, PyObject *unused)
2424+
test_interp_lock_countdown(PyObject *self, PyObject *unused)
24252425
{
24262426
PyInterpreterState *interp = PyInterpreterState_Get();
24272427
assert(_PyInterpreterState_LockCountdown(interp) == 0);
2428-
PyInterpreterLock refs[NUM_REFS];
2429-
for (int i = 0; i < NUM_REFS; ++i) {
2430-
int res = PyInterpreterLock_FromCurrent(&refs[i]);
2431-
(void)res;
2432-
assert(res == 0);
2428+
PyInterpreterLock locks[NUM_LOCKS];
2429+
for (int i = 0; i < NUM_LOCKS; ++i) {
2430+
locks[i] = PyInterpreterLock_FromCurrent();
2431+
assert(locks[i] != 0);
24332432
assert(_PyInterpreterState_LockCountdown(interp) == i + 1);
24342433
}
24352434

2436-
for (int i = 0; i < NUM_REFS; ++i) {
2437-
PyInterpreterLock_Release(refs[i]);
2438-
assert(_PyInterpreterState_LockCountdown(interp) == (NUM_REFS - i - 1));
2435+
for (int i = 0; i < NUM_LOCKS; ++i) {
2436+
PyInterpreterLock_Release(locks[i]);
2437+
assert(_PyInterpreterState_LockCountdown(interp) == (NUM_LOCKS - i - 1));
24392438
}
24402439

24412440
Py_RETURN_NONE;
24422441
}
24432442

24442443
static PyObject *
2445-
test_interp_weakref_incref(PyObject *self, PyObject *unused)
2444+
test_interp_view_countdown(PyObject *self, PyObject *unused)
24462445
{
24472446
PyInterpreterState *interp = PyInterpreterState_Get();
2448-
PyInterpreterView wref;
2449-
if (PyInterpreterView_FromCurrent(&wref) < 0) {
2447+
PyInterpreterView view = PyInterpreterView_FromCurrent();
2448+
if (view == 0) {
24502449
return NULL;
24512450
}
24522451
assert(_PyInterpreterState_LockCountdown(interp) == 0);
24532452

2454-
PyInterpreterLock refs[NUM_REFS];
2453+
PyInterpreterLock locks[NUM_LOCKS];
24552454

2456-
for (int i = 0; i < NUM_REFS; ++i) {
2457-
int res = PyInterpreterLock_FromView(wref, &refs[i]);
2458-
(void)res;
2459-
assert(res == 0);
2460-
assert(PyInterpreterLock_GetInterpreter(refs[i]) == interp);
2455+
for (int i = 0; i < NUM_LOCKS; ++i) {
2456+
locks[i] = PyInterpreterLock_FromView(view);
2457+
assert(locks[i] != 0);
2458+
assert(PyInterpreterLock_GetInterpreter(locks[i]) == interp);
24612459
assert(_PyInterpreterState_LockCountdown(interp) == i + 1);
24622460
}
24632461

2464-
for (int i = 0; i < NUM_REFS; ++i) {
2465-
PyInterpreterLock_Release(refs[i]);
2466-
assert(_PyInterpreterState_LockCountdown(interp) == (NUM_REFS - i - 1));
2462+
for (int i = 0; i < NUM_LOCKS; ++i) {
2463+
PyInterpreterLock_Release(locks[i]);
2464+
assert(_PyInterpreterState_LockCountdown(interp) == (NUM_LOCKS - i - 1));
24672465
}
24682466

2469-
PyInterpreterView_Close(wref);
2467+
PyInterpreterView_Close(view);
24702468
Py_RETURN_NONE;
24712469
}
24722470

2473-
#undef NUM_REFS
2471+
#undef NUM_LOCKS
24742472

24752473
static PyMethodDef module_functions[] = {
24762474
{"get_configs", get_configs, METH_NOARGS},
@@ -2581,8 +2579,8 @@ static PyMethodDef module_functions[] = {
25812579
#endif
25822580
{"set_vectorcall_nop", set_vectorcall_nop, METH_O},
25832581
{"simple_pending_call", simple_pending_call, METH_O},
2584-
{"test_interp_refcount", test_interp_refcount, METH_NOARGS},
2585-
{"test_interp_weakref_incref", test_interp_weakref_incref, METH_NOARGS},
2582+
{"test_interp_lock_countdown", test_interp_lock_countdown, METH_NOARGS},
2583+
{"test_interp_view_countdown", test_interp_view_countdown, METH_NOARGS},
25862584
{NULL, NULL} /* sentinel */
25872585
};
25882586

0 commit comments

Comments
 (0)