Skip to content

Commit caba55b

Browse files
authored
bpo-34301: Add _PyInterpreterState_Get() helper function (pythonGH-8592)
sys_setcheckinterval() now uses a local variable to parse arguments, before writing into interp->check_interval.
1 parent 2ebd381 commit caba55b

22 files changed

+107
-93
lines changed

Include/pystate.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -245,6 +245,13 @@ typedef struct _ts {
245245
PyAPI_FUNC(PyInterpreterState *) PyInterpreterState_New(void);
246246
PyAPI_FUNC(void) PyInterpreterState_Clear(PyInterpreterState *);
247247
PyAPI_FUNC(void) PyInterpreterState_Delete(PyInterpreterState *);
248+
#if !defined(Py_LIMITED_API)
249+
PyAPI_FUNC(PyInterpreterState *) _PyInterpreterState_Get(void);
250+
#endif
251+
#ifdef Py_BUILD_CORE
252+
/* Macro which should only be used for performance critical code */
253+
# define _PyInterpreterState_GET_UNSAFE() (PyThreadState_GET()->interp)
254+
#endif
248255
#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x03070000
249256
/* New in 3.7 */
250257
PyAPI_FUNC(int64_t) PyInterpreterState_GetID(PyInterpreterState *);

Modules/_threadmodule.c

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1049,7 +1049,7 @@ thread_PyThread_start_new_thread(PyObject *self, PyObject *fargs)
10491049
boot = PyMem_NEW(struct bootstate, 1);
10501050
if (boot == NULL)
10511051
return PyErr_NoMemory();
1052-
boot->interp = PyThreadState_GET()->interp;
1052+
boot->interp = _PyInterpreterState_Get();
10531053
boot->func = func;
10541054
boot->args = args;
10551055
boot->keyw = keyw;
@@ -1154,8 +1154,8 @@ A thread's identity may be reused for another thread after it exits.");
11541154
static PyObject *
11551155
thread__count(PyObject *self, PyObject *Py_UNUSED(ignored))
11561156
{
1157-
PyThreadState *tstate = PyThreadState_Get();
1158-
return PyLong_FromLong(tstate->interp->num_threads);
1157+
PyInterpreterState *interp = _PyInterpreterState_Get();
1158+
return PyLong_FromLong(interp->num_threads);
11591159
}
11601160

11611161
PyDoc_STRVAR(_count_doc,
@@ -1348,7 +1348,7 @@ PyInit__thread(void)
13481348
PyObject *m, *d, *v;
13491349
double time_max;
13501350
double timeout_max;
1351-
PyThreadState *tstate = PyThreadState_Get();
1351+
PyInterpreterState *interp = _PyInterpreterState_Get();
13521352

13531353
/* Initialize types: */
13541354
if (PyType_Ready(&localdummytype) < 0)
@@ -1395,7 +1395,7 @@ PyInit__thread(void)
13951395
if (PyModule_AddObject(m, "_local", (PyObject *)&localtype) < 0)
13961396
return NULL;
13971397

1398-
tstate->interp->num_threads = 0;
1398+
interp->num_threads = 0;
13991399

14001400
str_dict = PyUnicode_InternFromString("__dict__");
14011401
if (str_dict == NULL)

Modules/_xxsubinterpretersmodule.c

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -26,10 +26,9 @@ _copy_raw_string(PyObject *strobj)
2626
static PyInterpreterState *
2727
_get_current(void)
2828
{
29-
PyThreadState *tstate = PyThreadState_Get();
30-
// PyThreadState_Get() aborts if lookup fails, so we don't need
29+
// _PyInterpreterState_Get() aborts if lookup fails, so don't need
3130
// to check the result for NULL.
32-
return tstate->interp;
31+
return _PyInterpreterState_Get();
3332
}
3433

3534
static int64_t
@@ -1941,7 +1940,7 @@ _run_script_in_interpreter(PyInterpreterState *interp, const char *codestr,
19411940

19421941
// Switch to interpreter.
19431942
PyThreadState *save_tstate = NULL;
1944-
if (interp != PyThreadState_Get()->interp) {
1943+
if (interp != _PyInterpreterState_Get()) {
19451944
// XXX Using the "head" thread isn't strictly correct.
19461945
PyThreadState *tstate = PyInterpreterState_ThreadHead(interp);
19471946
// XXX Possible GILState issues?

Modules/posixmodule.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -437,7 +437,7 @@ run_at_forkers(PyObject *lst, int reverse)
437437
void
438438
PyOS_BeforeFork(void)
439439
{
440-
run_at_forkers(PyThreadState_Get()->interp->before_forkers, 1);
440+
run_at_forkers(_PyInterpreterState_Get()->before_forkers, 1);
441441

442442
_PyImport_AcquireLock();
443443
}
@@ -448,7 +448,7 @@ PyOS_AfterFork_Parent(void)
448448
if (_PyImport_ReleaseLock() <= 0)
449449
Py_FatalError("failed releasing import lock after fork");
450450

451-
run_at_forkers(PyThreadState_Get()->interp->after_forkers_parent, 0);
451+
run_at_forkers(_PyInterpreterState_Get()->after_forkers_parent, 0);
452452
}
453453

454454
void
@@ -459,7 +459,7 @@ PyOS_AfterFork_Child(void)
459459
_PyImport_ReInitLock();
460460
_PySignal_AfterFork();
461461

462-
run_at_forkers(PyThreadState_Get()->interp->after_forkers_child, 0);
462+
run_at_forkers(_PyInterpreterState_Get()->after_forkers_child, 0);
463463
}
464464

465465
static int
@@ -5655,7 +5655,7 @@ os_register_at_fork_impl(PyObject *module, PyObject *before,
56555655
check_null_or_callable(after_in_parent, "after_in_parent")) {
56565656
return NULL;
56575657
}
5658-
interp = PyThreadState_Get()->interp;
5658+
interp = _PyInterpreterState_Get();
56595659

56605660
if (register_at_forker(&interp->before_forkers, before)) {
56615661
return NULL;

Modules/zipimport.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1074,7 +1074,7 @@ read_directory(PyObject *archive)
10741074
if (flags & 0x0800) {
10751075
charset = "utf-8";
10761076
}
1077-
else if (!PyThreadState_GET()->interp->codecs_initialized) {
1077+
else if (!_PyInterpreterState_Get()->codecs_initialized) {
10781078
/* During bootstrap, we may need to load the encodings
10791079
package from a ZIP file. But the cp437 encoding is implemented
10801080
in Python in the encodings package.
@@ -1351,7 +1351,7 @@ unmarshal_code(PyObject *pathname, PyObject *data, time_t mtime)
13511351

13521352
uint32_t flags = get_uint32(buf + 4);
13531353
if (flags != 0) {
1354-
_PyCoreConfig *config = &PyThreadState_GET()->interp->core_config;
1354+
_PyCoreConfig *config = &_PyInterpreterState_Get()->core_config;
13551355
// Hash-based pyc. We currently refuse to handle checked hash-based
13561356
// pycs. We could validate hash-based pycs against the source, but it
13571357
// seems likely that most people putting hash-based pycs in a zipfile

Objects/codeobject.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
#include "Python.h"
44
#include "code.h"
55
#include "structmember.h"
6+
#include "internal/pystate.h"
67

78
/* Holder for co_extra information */
89
typedef struct {
@@ -428,7 +429,7 @@ static void
428429
code_dealloc(PyCodeObject *co)
429430
{
430431
if (co->co_extra != NULL) {
431-
PyInterpreterState *interp = PyThreadState_Get()->interp;
432+
PyInterpreterState *interp = _PyInterpreterState_GET_UNSAFE();
432433
_PyCodeObjectExtra *co_extra = co->co_extra;
433434

434435
for (Py_ssize_t i = 0; i < co_extra->ce_size; i++) {
@@ -871,7 +872,7 @@ _PyCode_GetExtra(PyObject *code, Py_ssize_t index, void **extra)
871872
int
872873
_PyCode_SetExtra(PyObject *code, Py_ssize_t index, void *extra)
873874
{
874-
PyInterpreterState *interp = PyThreadState_Get()->interp;
875+
PyInterpreterState *interp = _PyInterpreterState_GET_UNSAFE();
875876

876877
if (!PyCode_Check(code) || index < 0 ||
877878
index >= interp->co_extra_user_count) {

Objects/listobject.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@ static size_t count_reuse = 0;
8585
static void
8686
show_alloc(void)
8787
{
88-
PyInterpreterState *interp = PyThreadState_GET()->interp;
88+
PyInterpreterState *interp = _PyInterpreterState_Get();
8989
if (!interp->core_config.show_alloc_count) {
9090
return;
9191
}

Objects/moduleobject.c

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -173,7 +173,7 @@ _add_methods_to_object(PyObject *module, PyObject *name, PyMethodDef *functions)
173173
PyObject *
174174
PyModule_Create2(struct PyModuleDef* module, int module_api_version)
175175
{
176-
if (!_PyImport_IsInitialized(PyThreadState_GET()->interp))
176+
if (!_PyImport_IsInitialized(_PyInterpreterState_Get()))
177177
Py_FatalError("Python import machinery not initialized");
178178
return _PyModule_CreateInitialized(module, module_api_version);
179179
}
@@ -693,8 +693,7 @@ module_dealloc(PyModuleObject *m)
693693
static PyObject *
694694
module_repr(PyModuleObject *m)
695695
{
696-
PyThreadState *tstate = PyThreadState_GET();
697-
PyInterpreterState *interp = tstate->interp;
696+
PyInterpreterState *interp = _PyInterpreterState_Get();
698697

699698
return PyObject_CallMethod(interp->importlib, "_module_repr", "O", m);
700699
}

Objects/object.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,7 @@ extern Py_ssize_t null_strings, one_strings;
9696
void
9797
dump_counts(FILE* f)
9898
{
99-
PyInterpreterState *interp = PyThreadState_GET()->interp;
99+
PyInterpreterState *interp = _PyInterpreterState_Get();
100100
if (!interp->core_config.show_alloc_count) {
101101
return;
102102
}

Objects/tupleobject.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ static Py_ssize_t count_tracked = 0;
4444
static void
4545
show_track(void)
4646
{
47-
PyInterpreterState *interp = PyThreadState_GET()->interp;
47+
PyInterpreterState *interp = _PyInterpreterState_Get();
4848
if (!interp->core_config.show_alloc_count) {
4949
return;
5050
}

0 commit comments

Comments
 (0)