Skip to content

Commit a767e43

Browse files
committed
Remove opaque pointer types.
1 parent ba4c538 commit a767e43

6 files changed

Lines changed: 149 additions & 201 deletions

File tree

Include/cpython/pystate.h

Lines changed: 16 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -329,52 +329,24 @@ PyAPI_FUNC(_PyFrameEvalFunction) _PyInterpreterState_GetEvalFrameFunc(
329329
PyAPI_FUNC(void) _PyInterpreterState_SetEvalFrameFunc(
330330
PyInterpreterState *interp,
331331
_PyFrameEvalFunction eval_frame);
332-
333-
/* Interpreter guards */
334-
335-
typedef uintptr_t PyInterpreterGuard;
336-
typedef uintptr_t PyInterpreterView;
337-
338-
339-
PyAPI_FUNC(PyInterpreterGuard) PyInterpreterGuard_FromCurrent(void);
340-
PyAPI_FUNC(PyInterpreterGuard) PyInterpreterGuard_Copy(PyInterpreterGuard guard);
341-
PyAPI_FUNC(void) PyInterpreterGuard_Release(PyInterpreterGuard guard);
342-
PyAPI_FUNC(PyInterpreterState *) PyInterpreterGuard_GetInterpreter(PyInterpreterGuard guard);
343-
PyAPI_FUNC(PyInterpreterGuard) PyInterpreterGuard_FromView(PyInterpreterView view);
344-
345-
#ifdef Py_DEBUG
346-
#define PyInterpreterGuard_Release(guard) do { \
347-
PyInterpreterGuard_Release(guard); \
348-
guard = 0; \
349-
} while (0)
350-
#endif
351-
352-
/* Interpreter views */
353-
354-
typedef struct _PyInterpreterView {
355-
int64_t id;
356-
Py_ssize_t refcount;
357-
} _PyInterpreterView;
358-
359-
PyAPI_FUNC(PyInterpreterView) PyInterpreterView_FromCurrent(void);
360-
PyAPI_FUNC(PyInterpreterView) PyInterpreterView_Copy(PyInterpreterView view);
361-
PyAPI_FUNC(void) PyInterpreterView_Close(PyInterpreterView view);
362-
PyAPI_FUNC(PyInterpreterView) PyUnstable_InterpreterView_FromDefault(void);
363-
364-
365-
#ifdef Py_DEBUG
366-
#define PyInterpreterView_Close(view) do { \
367-
PyInterpreterView_Close(view); \
368-
view = 0; \
369-
} while (0)
370-
#endif
371-
372-
PyAPI_FUNC(PyThreadState *) PyThreadState_Ensure(PyInterpreterGuard guard);
373-
374-
PyAPI_FUNC(void) PyThreadState_Release(PyThreadState *tstate);
375-
376332
PyAPI_FUNC(void) _PyInterpreterState_SetEvalFrameAllowSpecialization(
377333
PyInterpreterState *interp,
378334
int allow_specialization);
379335
PyAPI_FUNC(int) _PyInterpreterState_IsSpecializationEnabled(
380336
PyInterpreterState *interp);
337+
338+
/* PEP 788 -- Interpreter guards and views. */
339+
340+
typedef struct _PyInterpreterGuard PyInterpreterGuard;
341+
typedef struct _PyInterpreterView PyInterpreterView;
342+
343+
PyAPI_FUNC(PyInterpreterGuard *) PyInterpreterGuard_FromCurrent(void);
344+
PyAPI_FUNC(void) PyInterpreterGuard_Close(PyInterpreterGuard *guard);
345+
PyAPI_FUNC(PyInterpreterGuard *) PyInterpreterGuard_FromView(PyInterpreterView *view);
346+
347+
PyAPI_FUNC(PyInterpreterView *) PyInterpreterView_FromCurrent(void);
348+
PyAPI_FUNC(void) PyInterpreterView_Close(PyInterpreterView *view);
349+
PyAPI_FUNC(PyInterpreterView *) PyInterpreterView_FromMain(void);
350+
351+
PyAPI_FUNC(PyThreadState *) PyThreadState_Ensure(PyInterpreterGuard *guard);
352+
PyAPI_FUNC(void) PyThreadState_Release(PyThreadState *tstate);

Include/internal/pycore_pystate.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -338,8 +338,20 @@ _Py_RecursionLimit_GetMargin(PyThreadState *tstate)
338338
#endif
339339
}
340340

341+
/* PEP 788 structures. */
342+
343+
struct _PyInterpreterGuard {
344+
PyInterpreterState *interp;
345+
};
346+
347+
struct _PyInterpreterView {
348+
int64_t id;
349+
Py_ssize_t refcount;
350+
};
351+
341352
// Exports for '_testinternalcapi' shared extension
342353
PyAPI_FUNC(Py_ssize_t) _PyInterpreterState_GuardCountdown(PyInterpreterState *interp);
354+
PyAPI_FUNC(PyInterpreterState *) _PyInterpreterGuard_GetInterpreter(PyInterpreterGuard *guard);
343355

344356
#ifdef __cplusplus
345357
}

Modules/_testcapimodule.c

Lines changed: 36 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -2609,18 +2609,15 @@ create_managed_weakref_nogc_type(PyObject *self, PyObject *Py_UNUSED(args))
26092609
static void
26102610
test_interp_guards_common(void)
26112611
{
2612-
PyInterpreterState *interp = PyInterpreterState_Get();
2613-
PyInterpreterGuard guard = PyInterpreterGuard_FromCurrent();
2614-
assert(guard != 0);
2615-
assert(PyInterpreterGuard_GetInterpreter(guard) == interp);
2612+
PyInterpreterGuard *guard = PyInterpreterGuard_FromCurrent();
2613+
assert(guard != NULL);
26162614

2617-
PyInterpreterGuard guard_2 = PyInterpreterGuard_Copy(guard);
2618-
assert(guard_2 != 0);
2619-
assert(PyInterpreterGuard_GetInterpreter(guard_2) == interp);
2615+
PyInterpreterGuard *guard_2 = PyInterpreterGuard_FromCurrent();
2616+
assert(guard_2 != NULL);
26202617

2621-
// We can close the references in any order
2622-
PyInterpreterGuard_Release(guard_2);
2623-
PyInterpreterGuard_Release(guard);
2618+
// We can close the guards in any order
2619+
PyInterpreterGuard_Close(guard_2);
2620+
PyInterpreterGuard_Close(guard);
26242621
}
26252622

26262623
static PyObject *
@@ -2657,25 +2654,25 @@ test_interpreter_guards(PyObject *self, PyObject *unused)
26572654
static PyObject *
26582655
test_thread_state_ensure_nested(PyObject *self, PyObject *unused)
26592656
{
2660-
PyInterpreterGuard guard = PyInterpreterGuard_FromCurrent();
2661-
if (guard == 0) {
2657+
PyInterpreterGuard *guard = PyInterpreterGuard_FromCurrent();
2658+
if (guard == NULL) {
26622659
return NULL;
26632660
}
26642661
PyThreadState *save_tstate = PyThreadState_Swap(NULL);
26652662
assert(PyGILState_GetThisThreadState() == save_tstate);
2666-
PyThreadState * thread_views[10];
2663+
PyThreadState *thread_states[10];
26672664

26682665
for (int i = 0; i < 10; ++i) {
26692666
// Test reactivation of the detached tstate.
2670-
thread_views[i] = PyThreadState_Ensure(guard);
2671-
if (thread_views[i] == 0) {
2672-
PyInterpreterGuard_Release(guard);
2667+
thread_states[i] = PyThreadState_Ensure(guard);
2668+
if (thread_states[i] == 0) {
2669+
PyInterpreterGuard_Close(guard);
26732670
return PyErr_NoMemory();
26742671
}
26752672

26762673
// No new thread state should've been created.
26772674
assert(PyThreadState_Get() == save_tstate);
2678-
PyThreadState_Release(thread_views[i]);
2675+
PyThreadState_Release(thread_states[i]);
26792676
}
26802677

26812678
assert(PyThreadState_GetUnchecked() == NULL);
@@ -2684,11 +2681,11 @@ test_thread_state_ensure_nested(PyObject *self, PyObject *unused)
26842681
// If the (detached) gilstate matches the interpreter, then it shouldn't
26852682
// create a new thread state.
26862683
for (int i = 0; i < 10; ++i) {
2687-
thread_views[i] = PyThreadState_Ensure(guard);
2688-
if (thread_views[i] == 0) {
2684+
thread_states[i] = PyThreadState_Ensure(guard);
2685+
if (thread_states[i] == 0) {
26892686
// This will technically leak other thread states, but it doesn't
26902687
// matter because this is a test.
2691-
PyInterpreterGuard_Release(guard);
2688+
PyInterpreterGuard_Close(guard);
26922689
return PyErr_NoMemory();
26932690
}
26942691

@@ -2697,23 +2694,23 @@ test_thread_state_ensure_nested(PyObject *self, PyObject *unused)
26972694

26982695
for (int i = 0; i < 10; ++i) {
26992696
assert(PyThreadState_Get() == save_tstate);
2700-
PyThreadState_Release(thread_views[i]);
2697+
PyThreadState_Release(thread_states[i]);
27012698
}
27022699

27032700
assert(PyThreadState_GetUnchecked() == NULL);
2704-
PyInterpreterGuard_Release(guard);
2701+
PyInterpreterGuard_Close(guard);
27052702
PyThreadState_Swap(save_tstate);
27062703
Py_RETURN_NONE;
27072704
}
27082705

27092706
static PyObject *
27102707
test_thread_state_ensure_crossinterp(PyObject *self, PyObject *unused)
27112708
{
2712-
PyInterpreterGuard guard = PyInterpreterGuard_FromCurrent();
2709+
PyInterpreterGuard *guard = PyInterpreterGuard_FromCurrent();
27132710
PyThreadState *save_tstate = PyThreadState_Swap(NULL);
27142711
PyThreadState *interp_tstate = Py_NewInterpreter();
27152712
if (interp_tstate == NULL) {
2716-
PyInterpreterGuard_Release(guard);
2713+
PyInterpreterGuard_Close(guard);
27172714
return PyErr_NoMemory();
27182715
}
27192716

@@ -2730,37 +2727,36 @@ test_thread_state_ensure_crossinterp(PyObject *self, PyObject *unused)
27302727
interp = interpreters.create()
27312728
interp.exec(some_func)
27322729
*/
2733-
PyThreadState * thread_view = PyThreadState_Ensure(guard);
2734-
if (thread_view == 0) {
2735-
PyInterpreterGuard_Release(guard);
2730+
PyThreadState *thread_state = PyThreadState_Ensure(guard);
2731+
if (thread_state == NULL) {
2732+
PyInterpreterGuard_Close(guard);
27362733
return PyErr_NoMemory();
27372734
}
27382735

27392736
PyThreadState *ensured_tstate = PyThreadState_Get();
27402737
assert(ensured_tstate != save_tstate);
2741-
assert(PyInterpreterState_Get() == PyInterpreterGuard_GetInterpreter(guard));
27422738
assert(PyGILState_GetThisThreadState() == ensured_tstate);
27432739

27442740
// Now though, we should reactivate the thread state
2745-
PyThreadState * other_thread_view = PyThreadState_Ensure(guard);
2746-
if (other_thread_view == 0) {
2747-
PyThreadState_Release(thread_view);
2748-
PyInterpreterGuard_Release(guard);
2741+
PyThreadState *other_thread_state = PyThreadState_Ensure(guard);
2742+
if (other_thread_state == NULL) {
2743+
PyThreadState_Release(thread_state);
2744+
PyInterpreterGuard_Close(guard);
27492745
return PyErr_NoMemory();
27502746
}
27512747

27522748
assert(PyThreadState_Get() == ensured_tstate);
2753-
PyThreadState_Release(other_thread_view);
2749+
PyThreadState_Release(other_thread_state);
27542750

27552751
// Ensure that we're restoring the prior thread state
2756-
PyThreadState_Release(thread_view);
2752+
PyThreadState_Release(thread_state);
27572753
assert(PyThreadState_Get() == interp_tstate);
27582754
assert(PyGILState_GetThisThreadState() == interp_tstate);
27592755

27602756
PyThreadState_Swap(interp_tstate);
27612757
Py_EndInterpreter(interp_tstate);
27622758

2763-
PyInterpreterGuard_Release(guard);
2759+
PyInterpreterGuard_Close(guard);
27642760
PyThreadState_Swap(save_tstate);
27652761
Py_RETURN_NONE;
27662762
}
@@ -2774,20 +2770,20 @@ test_interp_view_after_shutdown(PyObject *self, PyObject *unused)
27742770
return PyErr_NoMemory();
27752771
}
27762772

2777-
PyInterpreterView view = PyInterpreterView_FromCurrent();
2778-
if (view == 0) {
2773+
PyInterpreterView *view = PyInterpreterView_FromCurrent();
2774+
if (view == NULL) {
27792775
return PyErr_NoMemory();
27802776
}
27812777

27822778
// As a sanity check, ensure that the view actually works
2783-
PyInterpreterGuard guard = PyInterpreterGuard_FromView(view);
2784-
PyInterpreterGuard_Release(guard);
2779+
PyInterpreterGuard *guard = PyInterpreterGuard_FromView(view);
2780+
PyInterpreterGuard_Close(guard);
27852781

27862782
// Now, destroy the interpreter and try to acquire a lock from a view.
27872783
// It should fail.
27882784
Py_EndInterpreter(interp_tstate);
27892785
guard = PyInterpreterGuard_FromView(view);
2790-
assert(guard == 0);
2786+
assert(guard == NULL);
27912787

27922788
PyThreadState_Swap(save_tstate);
27932789
Py_RETURN_NONE;

Modules/_testinternalcapi.c

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2883,15 +2883,15 @@ test_interp_guard_countdown(PyObject *self, PyObject *unused)
28832883
{
28842884
PyInterpreterState *interp = PyInterpreterState_Get();
28852885
assert(_PyInterpreterState_GuardCountdown(interp) == 0);
2886-
PyInterpreterGuard guards[NUM_GUARDS];
2886+
PyInterpreterGuard *guards[NUM_GUARDS];
28872887
for (int i = 0; i < NUM_GUARDS; ++i) {
28882888
guards[i] = PyInterpreterGuard_FromCurrent();
28892889
assert(guards[i] != 0);
28902890
assert(_PyInterpreterState_GuardCountdown(interp) == i + 1);
28912891
}
28922892

28932893
for (int i = 0; i < NUM_GUARDS; ++i) {
2894-
PyInterpreterGuard_Release(guards[i]);
2894+
PyInterpreterGuard_Close(guards[i]);
28952895
assert(_PyInterpreterState_GuardCountdown(interp) == (NUM_GUARDS - i - 1));
28962896
}
28972897

@@ -2902,23 +2902,23 @@ static PyObject *
29022902
test_interp_view_countdown(PyObject *self, PyObject *unused)
29032903
{
29042904
PyInterpreterState *interp = PyInterpreterState_Get();
2905-
PyInterpreterView view = PyInterpreterView_FromCurrent();
2906-
if (view == 0) {
2905+
PyInterpreterView *view = PyInterpreterView_FromCurrent();
2906+
if (view == NULL) {
29072907
return NULL;
29082908
}
29092909
assert(_PyInterpreterState_GuardCountdown(interp) == 0);
29102910

2911-
PyInterpreterGuard guards[NUM_GUARDS];
2911+
PyInterpreterGuard *guards[NUM_GUARDS];
29122912

29132913
for (int i = 0; i < NUM_GUARDS; ++i) {
29142914
guards[i] = PyInterpreterGuard_FromView(view);
29152915
assert(guards[i] != 0);
2916-
assert(PyInterpreterGuard_GetInterpreter(guards[i]) == interp);
2916+
assert(_PyInterpreterGuard_GetInterpreter(guards[i]) == interp);
29172917
assert(_PyInterpreterState_GuardCountdown(interp) == i + 1);
29182918
}
29192919

29202920
for (int i = 0; i < NUM_GUARDS; ++i) {
2921-
PyInterpreterGuard_Release(guards[i]);
2921+
PyInterpreterGuard_Close(guards[i]);
29222922
assert(_PyInterpreterState_GuardCountdown(interp) == (NUM_GUARDS - i - 1));
29232923
}
29242924

Programs/_testembed.c

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -2682,15 +2682,15 @@ const char *THREAD_CODE = \
26822682
"fib(10)";
26832683

26842684
typedef struct {
2685-
PyInterpreterGuard guard;
2685+
PyInterpreterGuard *guard;
26862686
int done;
26872687
} ThreadData;
26882688

26892689
static void
26902690
do_tstate_ensure(void *arg)
26912691
{
26922692
ThreadData *data = (ThreadData *)arg;
2693-
PyThreadState * refs[4];
2693+
PyThreadState *refs[4];
26942694
refs[0] = PyThreadState_Ensure(data->guard);
26952695
refs[1] = PyThreadState_Ensure(data->guard);
26962696
refs[2] = PyThreadState_Ensure(data->guard);
@@ -2707,7 +2707,7 @@ do_tstate_ensure(void *arg)
27072707
PyThreadState_Release(refs[2]);
27082708
PyThreadState_Release(refs[1]);
27092709
PyThreadState_Release(refs[0]);
2710-
PyInterpreterGuard_Release(data->guard);
2710+
PyInterpreterGuard_Close(data->guard);
27112711
data->done = 1;
27122712
}
27132713

@@ -2717,14 +2717,14 @@ test_thread_state_ensure(void)
27172717
_testembed_initialize();
27182718
PyThread_handle_t handle;
27192719
PyThread_ident_t ident;
2720-
PyInterpreterGuard guard = PyInterpreterGuard_FromCurrent();
2721-
if (guard == 0) {
2720+
PyInterpreterGuard *guard = PyInterpreterGuard_FromCurrent();
2721+
if (guard == NULL) {
27222722
return -1;
27232723
};
27242724
ThreadData data = { guard };
27252725
if (PyThread_start_joinable_thread(do_tstate_ensure, &data,
27262726
&ident, &handle) < 0) {
2727-
PyInterpreterGuard_Release(guard);
2727+
PyInterpreterGuard_Close(guard);
27282728
return -1;
27292729
}
27302730
// We hold an interpreter guard, so we don't
@@ -2741,18 +2741,18 @@ test_main_interpreter_view(void)
27412741
_testembed_initialize();
27422742

27432743
// Main interpreter is initialized and ready.
2744-
PyInterpreterView view = PyUnstable_InterpreterView_FromDefault();
2745-
assert(view != 0);
2744+
PyInterpreterView *view = PyInterpreterView_FromMain();
2745+
assert(view != NULL);
27462746

2747-
PyInterpreterGuard guard = PyInterpreterGuard_FromView(view);
2748-
assert(guard != 0);
2749-
PyInterpreterGuard_Release(guard);
2747+
PyInterpreterGuard *guard = PyInterpreterGuard_FromView(view);
2748+
assert(guard != NULL);
2749+
PyInterpreterGuard_Close(guard);
27502750

27512751
Py_Finalize();
27522752

27532753
// We shouldn't be able to get locks for the interpreter now
27542754
guard = PyInterpreterGuard_FromView(view);
2755-
assert(guard == 0);
2755+
assert(guard == NULL);
27562756

27572757
PyInterpreterView_Close(view);
27582758

0 commit comments

Comments
 (0)