Skip to content

gh-105603: Change the PyInterpreterConfig.own gil Field #105620

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 7 additions & 3 deletions Include/cpython/initconfig.h
Original file line number Diff line number Diff line change
Expand Up @@ -244,6 +244,10 @@ PyAPI_FUNC(PyStatus) PyConfig_SetWideStringList(PyConfig *config,

/* --- PyInterpreterConfig ------------------------------------ */

#define PyInterpreterConfig_DEFAULT_GIL (0)
#define PyInterpreterConfig_SHARED_GIL (1)
#define PyInterpreterConfig_OWN_GIL (2)

typedef struct {
// XXX "allow_object_sharing"? "own_objects"?
int use_main_obmalloc;
Expand All @@ -252,7 +256,7 @@ typedef struct {
int allow_threads;
int allow_daemon_threads;
int check_multi_interp_extensions;
int own_gil;
int gil;
} PyInterpreterConfig;

#define _PyInterpreterConfig_INIT \
Expand All @@ -263,7 +267,7 @@ typedef struct {
.allow_threads = 1, \
.allow_daemon_threads = 0, \
.check_multi_interp_extensions = 1, \
.own_gil = 1, \
.gil = PyInterpreterConfig_OWN_GIL, \
}

#define _PyInterpreterConfig_LEGACY_INIT \
Expand All @@ -274,7 +278,7 @@ typedef struct {
.allow_threads = 1, \
.allow_daemon_threads = 1, \
.check_multi_interp_extensions = 0, \
.own_gil = 0, \
.gil = PyInterpreterConfig_SHARED_GIL, \
}

/* --- Helper functions --------------------------------------- */
Expand Down
5 changes: 4 additions & 1 deletion Lib/test/support/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -1813,13 +1813,16 @@ def run_in_subinterp(code):
return _testcapi.run_in_subinterp(code)


def run_in_subinterp_with_config(code, **config):
def run_in_subinterp_with_config(code, *, own_gil=None, **config):
"""
Run code in a subinterpreter. Raise unittest.SkipTest if the tracemalloc
module is enabled.
"""
_check_tracemalloc()
import _testcapi
if own_gil is not None:
assert 'gil' not in config, (own_gil, config)
config['gil'] = 2 if own_gil else 1
return _testcapi.run_in_subinterp_with_config(code, **config)


Expand Down
3 changes: 2 additions & 1 deletion Lib/test/test_import/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -1640,9 +1640,10 @@ class SubinterpImportTests(unittest.TestCase):
)
ISOLATED = dict(
use_main_obmalloc=False,
own_gil=True,
gil=2,
)
NOT_ISOLATED = {k: not v for k, v in ISOLATED.items()}
NOT_ISOLATED['gil'] = 1

@unittest.skipUnless(hasattr(os, "pipe"), "requires os.pipe()")
def pipe(self):
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
We've renamed the new (in 3.12) ``PyInterpreterConfig.own_gil`` to
``PyInterpreterConfig.gil`` and changed the meaning of the value from "bool"
to an integer with supported values of ``PyInterpreterConfig_DEFAULT_GIL``,
``PyInterpreterConfig_SHARED_GIL``, and ``PyInterpreterConfig_OWN_GIL``. The
default is "shared".
14 changes: 7 additions & 7 deletions Modules/_testcapimodule.c
Original file line number Diff line number Diff line change
Expand Up @@ -1426,7 +1426,7 @@ run_in_subinterp_with_config(PyObject *self, PyObject *args, PyObject *kwargs)
int allow_threads = -1;
int allow_daemon_threads = -1;
int check_multi_interp_extensions = -1;
int own_gil = -1;
int gil = -1;
int r;
PyThreadState *substate, *mainstate;
/* only initialise 'cflags.cf_flags' to test backwards compatibility */
Expand All @@ -1439,15 +1439,15 @@ run_in_subinterp_with_config(PyObject *self, PyObject *args, PyObject *kwargs)
"allow_threads",
"allow_daemon_threads",
"check_multi_interp_extensions",
"own_gil",
"gil",
NULL};
if (!PyArg_ParseTupleAndKeywords(args, kwargs,
"s$ppppppp:run_in_subinterp_with_config", kwlist,
"s$ppppppi:run_in_subinterp_with_config", kwlist,
&code, &use_main_obmalloc,
&allow_fork, &allow_exec,
&allow_threads, &allow_daemon_threads,
&check_multi_interp_extensions,
&own_gil)) {
&gil)) {
return NULL;
}
if (use_main_obmalloc < 0) {
Expand All @@ -1466,8 +1466,8 @@ run_in_subinterp_with_config(PyObject *self, PyObject *args, PyObject *kwargs)
PyErr_SetString(PyExc_ValueError, "missing allow_threads");
return NULL;
}
if (own_gil < 0) {
PyErr_SetString(PyExc_ValueError, "missing own_gil");
if (gil < 0) {
PyErr_SetString(PyExc_ValueError, "missing gil");
return NULL;
}
if (allow_daemon_threads < 0) {
Expand All @@ -1490,7 +1490,7 @@ run_in_subinterp_with_config(PyObject *self, PyObject *args, PyObject *kwargs)
.allow_threads = allow_threads,
.allow_daemon_threads = allow_daemon_threads,
.check_multi_interp_extensions = check_multi_interp_extensions,
.own_gil = own_gil,
.gil = gil,
};
PyStatus status = Py_NewInterpreterFromConfig(&substate, &config);
if (PyStatus_Exception(status)) {
Expand Down
19 changes: 15 additions & 4 deletions Python/pylifecycle.c
Original file line number Diff line number Diff line change
Expand Up @@ -578,12 +578,14 @@ init_interp_settings(PyInterpreterState *interp,
interp->feature_flags |= Py_RTFLAGS_MULTI_INTERP_EXTENSIONS;
}

/* We check "gil" in init_interp_create_gil(). */

return _PyStatus_OK();
}


static PyStatus
init_interp_create_gil(PyThreadState *tstate, int own_gil)
init_interp_create_gil(PyThreadState *tstate, int gil)
{
PyStatus status;

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

int own_gil;
switch (gil) {
case PyInterpreterConfig_DEFAULT_GIL: own_gil = 0; break;
case PyInterpreterConfig_SHARED_GIL: own_gil = 0; break;
case PyInterpreterConfig_OWN_GIL: own_gil = 1; break;
default:
return _PyStatus_ERR("invalid interpreter config 'gil' value");
}

/* Create the GIL and take it */
status = _PyEval_InitGIL(tstate, own_gil);
if (_PyStatus_EXCEPTION(status)) {
Expand Down Expand Up @@ -633,7 +644,7 @@ pycore_create_interpreter(_PyRuntimeState *runtime,

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

status = init_interp_create_gil(tstate, config.own_gil);
status = init_interp_create_gil(tstate, config.gil);
if (_PyStatus_EXCEPTION(status)) {
return status;
}
Expand Down Expand Up @@ -2057,7 +2068,7 @@ new_interpreter(PyThreadState **tstate_p, const PyInterpreterConfig *config)
goto error;
}

status = init_interp_create_gil(tstate, config->own_gil);
status = init_interp_create_gil(tstate, config->gil);
if (_PyStatus_EXCEPTION(status)) {
goto error;
}
Expand Down