Skip to content

Commit b97e14a

Browse files
gh-105603: Change the PyInterpreterConfig.own gil Field (gh-105620)
We are changing it to be more flexible that a strict bool can be for possible future expanded used cases.
1 parent abfbab6 commit b97e14a

File tree

6 files changed

+40
-16
lines changed

6 files changed

+40
-16
lines changed

Include/cpython/initconfig.h

+7-3
Original file line numberDiff line numberDiff line change
@@ -244,6 +244,10 @@ PyAPI_FUNC(PyStatus) PyConfig_SetWideStringList(PyConfig *config,
244244

245245
/* --- PyInterpreterConfig ------------------------------------ */
246246

247+
#define PyInterpreterConfig_DEFAULT_GIL (0)
248+
#define PyInterpreterConfig_SHARED_GIL (1)
249+
#define PyInterpreterConfig_OWN_GIL (2)
250+
247251
typedef struct {
248252
// XXX "allow_object_sharing"? "own_objects"?
249253
int use_main_obmalloc;
@@ -252,7 +256,7 @@ typedef struct {
252256
int allow_threads;
253257
int allow_daemon_threads;
254258
int check_multi_interp_extensions;
255-
int own_gil;
259+
int gil;
256260
} PyInterpreterConfig;
257261

258262
#define _PyInterpreterConfig_INIT \
@@ -263,7 +267,7 @@ typedef struct {
263267
.allow_threads = 1, \
264268
.allow_daemon_threads = 0, \
265269
.check_multi_interp_extensions = 1, \
266-
.own_gil = 1, \
270+
.gil = PyInterpreterConfig_OWN_GIL, \
267271
}
268272

269273
#define _PyInterpreterConfig_LEGACY_INIT \
@@ -274,7 +278,7 @@ typedef struct {
274278
.allow_threads = 1, \
275279
.allow_daemon_threads = 1, \
276280
.check_multi_interp_extensions = 0, \
277-
.own_gil = 0, \
281+
.gil = PyInterpreterConfig_SHARED_GIL, \
278282
}
279283

280284
/* --- Helper functions --------------------------------------- */

Lib/test/support/__init__.py

+4-1
Original file line numberDiff line numberDiff line change
@@ -1813,13 +1813,16 @@ def run_in_subinterp(code):
18131813
return _testcapi.run_in_subinterp(code)
18141814

18151815

1816-
def run_in_subinterp_with_config(code, **config):
1816+
def run_in_subinterp_with_config(code, *, own_gil=None, **config):
18171817
"""
18181818
Run code in a subinterpreter. Raise unittest.SkipTest if the tracemalloc
18191819
module is enabled.
18201820
"""
18211821
_check_tracemalloc()
18221822
import _testcapi
1823+
if own_gil is not None:
1824+
assert 'gil' not in config, (own_gil, config)
1825+
config['gil'] = 2 if own_gil else 1
18231826
return _testcapi.run_in_subinterp_with_config(code, **config)
18241827

18251828

Lib/test/test_import/__init__.py

+2-1
Original file line numberDiff line numberDiff line change
@@ -1640,9 +1640,10 @@ class SubinterpImportTests(unittest.TestCase):
16401640
)
16411641
ISOLATED = dict(
16421642
use_main_obmalloc=False,
1643-
own_gil=True,
1643+
gil=2,
16441644
)
16451645
NOT_ISOLATED = {k: not v for k, v in ISOLATED.items()}
1646+
NOT_ISOLATED['gil'] = 1
16461647

16471648
@unittest.skipUnless(hasattr(os, "pipe"), "requires os.pipe()")
16481649
def pipe(self):
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
We've renamed the new (in 3.12) ``PyInterpreterConfig.own_gil`` to
2+
``PyInterpreterConfig.gil`` and changed the meaning of the value from "bool"
3+
to an integer with supported values of ``PyInterpreterConfig_DEFAULT_GIL``,
4+
``PyInterpreterConfig_SHARED_GIL``, and ``PyInterpreterConfig_OWN_GIL``. The
5+
default is "shared".

Modules/_testcapimodule.c

+7-7
Original file line numberDiff line numberDiff line change
@@ -1426,7 +1426,7 @@ run_in_subinterp_with_config(PyObject *self, PyObject *args, PyObject *kwargs)
14261426
int allow_threads = -1;
14271427
int allow_daemon_threads = -1;
14281428
int check_multi_interp_extensions = -1;
1429-
int own_gil = -1;
1429+
int gil = -1;
14301430
int r;
14311431
PyThreadState *substate, *mainstate;
14321432
/* only initialise 'cflags.cf_flags' to test backwards compatibility */
@@ -1439,15 +1439,15 @@ run_in_subinterp_with_config(PyObject *self, PyObject *args, PyObject *kwargs)
14391439
"allow_threads",
14401440
"allow_daemon_threads",
14411441
"check_multi_interp_extensions",
1442-
"own_gil",
1442+
"gil",
14431443
NULL};
14441444
if (!PyArg_ParseTupleAndKeywords(args, kwargs,
1445-
"s$ppppppp:run_in_subinterp_with_config", kwlist,
1445+
"s$ppppppi:run_in_subinterp_with_config", kwlist,
14461446
&code, &use_main_obmalloc,
14471447
&allow_fork, &allow_exec,
14481448
&allow_threads, &allow_daemon_threads,
14491449
&check_multi_interp_extensions,
1450-
&own_gil)) {
1450+
&gil)) {
14511451
return NULL;
14521452
}
14531453
if (use_main_obmalloc < 0) {
@@ -1466,8 +1466,8 @@ run_in_subinterp_with_config(PyObject *self, PyObject *args, PyObject *kwargs)
14661466
PyErr_SetString(PyExc_ValueError, "missing allow_threads");
14671467
return NULL;
14681468
}
1469-
if (own_gil < 0) {
1470-
PyErr_SetString(PyExc_ValueError, "missing own_gil");
1469+
if (gil < 0) {
1470+
PyErr_SetString(PyExc_ValueError, "missing gil");
14711471
return NULL;
14721472
}
14731473
if (allow_daemon_threads < 0) {
@@ -1490,7 +1490,7 @@ run_in_subinterp_with_config(PyObject *self, PyObject *args, PyObject *kwargs)
14901490
.allow_threads = allow_threads,
14911491
.allow_daemon_threads = allow_daemon_threads,
14921492
.check_multi_interp_extensions = check_multi_interp_extensions,
1493-
.own_gil = own_gil,
1493+
.gil = gil,
14941494
};
14951495
PyStatus status = Py_NewInterpreterFromConfig(&substate, &config);
14961496
if (PyStatus_Exception(status)) {

Python/pylifecycle.c

+15-4
Original file line numberDiff line numberDiff line change
@@ -578,12 +578,14 @@ init_interp_settings(PyInterpreterState *interp,
578578
interp->feature_flags |= Py_RTFLAGS_MULTI_INTERP_EXTENSIONS;
579579
}
580580

581+
/* We check "gil" in init_interp_create_gil(). */
582+
581583
return _PyStatus_OK();
582584
}
583585

584586

585587
static PyStatus
586-
init_interp_create_gil(PyThreadState *tstate, int own_gil)
588+
init_interp_create_gil(PyThreadState *tstate, int gil)
587589
{
588590
PyStatus status;
589591

@@ -598,6 +600,15 @@ init_interp_create_gil(PyThreadState *tstate, int own_gil)
598600
return status;
599601
}
600602

603+
int own_gil;
604+
switch (gil) {
605+
case PyInterpreterConfig_DEFAULT_GIL: own_gil = 0; break;
606+
case PyInterpreterConfig_SHARED_GIL: own_gil = 0; break;
607+
case PyInterpreterConfig_OWN_GIL: own_gil = 1; break;
608+
default:
609+
return _PyStatus_ERR("invalid interpreter config 'gil' value");
610+
}
611+
601612
/* Create the GIL and take it */
602613
status = _PyEval_InitGIL(tstate, own_gil);
603614
if (_PyStatus_EXCEPTION(status)) {
@@ -633,7 +644,7 @@ pycore_create_interpreter(_PyRuntimeState *runtime,
633644

634645
PyInterpreterConfig config = _PyInterpreterConfig_LEGACY_INIT;
635646
// The main interpreter always has its own GIL.
636-
config.own_gil = 1;
647+
config.gil = PyInterpreterConfig_OWN_GIL;
637648
status = init_interp_settings(interp, &config);
638649
if (_PyStatus_EXCEPTION(status)) {
639650
return status;
@@ -647,7 +658,7 @@ pycore_create_interpreter(_PyRuntimeState *runtime,
647658
// XXX For now we do this before the GIL is created.
648659
(void) _PyThreadState_SwapNoGIL(tstate);
649660

650-
status = init_interp_create_gil(tstate, config.own_gil);
661+
status = init_interp_create_gil(tstate, config.gil);
651662
if (_PyStatus_EXCEPTION(status)) {
652663
return status;
653664
}
@@ -2057,7 +2068,7 @@ new_interpreter(PyThreadState **tstate_p, const PyInterpreterConfig *config)
20572068
goto error;
20582069
}
20592070

2060-
status = init_interp_create_gil(tstate, config->own_gil);
2071+
status = init_interp_create_gil(tstate, config->gil);
20612072
if (_PyStatus_EXCEPTION(status)) {
20622073
goto error;
20632074
}

0 commit comments

Comments
 (0)