mirror of
https://github.com/python/cpython.git
synced 2025-07-23 19:25:40 +00:00
[3.12] gh-105603: Change the PyInterpreterConfig.own gil Field (gh-105620) (gh-105731)
We are changing it to be more flexible that a strict bool can be for possible future expanded used cases.
(cherry picked from commit b97e14a806
)
Co-authored-by: Eric Snow <ericsnowcurrently@gmail.com>
This commit is contained in:
parent
9c51ea5d55
commit
c3a2cbb54d
6 changed files with 40 additions and 16 deletions
|
@ -244,6 +244,10 @@ PyAPI_FUNC(PyStatus) PyConfig_SetWideStringList(PyConfig *config,
|
||||||
|
|
||||||
/* --- PyInterpreterConfig ------------------------------------ */
|
/* --- PyInterpreterConfig ------------------------------------ */
|
||||||
|
|
||||||
|
#define PyInterpreterConfig_DEFAULT_GIL (0)
|
||||||
|
#define PyInterpreterConfig_SHARED_GIL (1)
|
||||||
|
#define PyInterpreterConfig_OWN_GIL (2)
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
// XXX "allow_object_sharing"? "own_objects"?
|
// XXX "allow_object_sharing"? "own_objects"?
|
||||||
int use_main_obmalloc;
|
int use_main_obmalloc;
|
||||||
|
@ -252,7 +256,7 @@ typedef struct {
|
||||||
int allow_threads;
|
int allow_threads;
|
||||||
int allow_daemon_threads;
|
int allow_daemon_threads;
|
||||||
int check_multi_interp_extensions;
|
int check_multi_interp_extensions;
|
||||||
int own_gil;
|
int gil;
|
||||||
} PyInterpreterConfig;
|
} PyInterpreterConfig;
|
||||||
|
|
||||||
#define _PyInterpreterConfig_INIT \
|
#define _PyInterpreterConfig_INIT \
|
||||||
|
@ -263,7 +267,7 @@ typedef struct {
|
||||||
.allow_threads = 1, \
|
.allow_threads = 1, \
|
||||||
.allow_daemon_threads = 0, \
|
.allow_daemon_threads = 0, \
|
||||||
.check_multi_interp_extensions = 1, \
|
.check_multi_interp_extensions = 1, \
|
||||||
.own_gil = 1, \
|
.gil = PyInterpreterConfig_OWN_GIL, \
|
||||||
}
|
}
|
||||||
|
|
||||||
#define _PyInterpreterConfig_LEGACY_INIT \
|
#define _PyInterpreterConfig_LEGACY_INIT \
|
||||||
|
@ -274,7 +278,7 @@ typedef struct {
|
||||||
.allow_threads = 1, \
|
.allow_threads = 1, \
|
||||||
.allow_daemon_threads = 1, \
|
.allow_daemon_threads = 1, \
|
||||||
.check_multi_interp_extensions = 0, \
|
.check_multi_interp_extensions = 0, \
|
||||||
.own_gil = 0, \
|
.gil = PyInterpreterConfig_SHARED_GIL, \
|
||||||
}
|
}
|
||||||
|
|
||||||
/* --- Helper functions --------------------------------------- */
|
/* --- Helper functions --------------------------------------- */
|
||||||
|
|
|
@ -1813,13 +1813,16 @@ def run_in_subinterp(code):
|
||||||
return _testcapi.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
|
Run code in a subinterpreter. Raise unittest.SkipTest if the tracemalloc
|
||||||
module is enabled.
|
module is enabled.
|
||||||
"""
|
"""
|
||||||
_check_tracemalloc()
|
_check_tracemalloc()
|
||||||
import _testcapi
|
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)
|
return _testcapi.run_in_subinterp_with_config(code, **config)
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1640,9 +1640,10 @@ class SubinterpImportTests(unittest.TestCase):
|
||||||
)
|
)
|
||||||
ISOLATED = dict(
|
ISOLATED = dict(
|
||||||
use_main_obmalloc=False,
|
use_main_obmalloc=False,
|
||||||
own_gil=True,
|
gil=2,
|
||||||
)
|
)
|
||||||
NOT_ISOLATED = {k: not v for k, v in ISOLATED.items()}
|
NOT_ISOLATED = {k: not v for k, v in ISOLATED.items()}
|
||||||
|
NOT_ISOLATED['gil'] = 1
|
||||||
|
|
||||||
@unittest.skipUnless(hasattr(os, "pipe"), "requires os.pipe()")
|
@unittest.skipUnless(hasattr(os, "pipe"), "requires os.pipe()")
|
||||||
def pipe(self):
|
def pipe(self):
|
||||||
|
|
|
@ -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".
|
|
@ -1426,7 +1426,7 @@ run_in_subinterp_with_config(PyObject *self, PyObject *args, PyObject *kwargs)
|
||||||
int allow_threads = -1;
|
int allow_threads = -1;
|
||||||
int allow_daemon_threads = -1;
|
int allow_daemon_threads = -1;
|
||||||
int check_multi_interp_extensions = -1;
|
int check_multi_interp_extensions = -1;
|
||||||
int own_gil = -1;
|
int gil = -1;
|
||||||
int r;
|
int r;
|
||||||
PyThreadState *substate, *mainstate;
|
PyThreadState *substate, *mainstate;
|
||||||
/* only initialise 'cflags.cf_flags' to test backwards compatibility */
|
/* only initialise 'cflags.cf_flags' to test backwards compatibility */
|
||||||
|
@ -1439,15 +1439,15 @@ 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",
|
"gil",
|
||||||
NULL};
|
NULL};
|
||||||
if (!PyArg_ParseTupleAndKeywords(args, kwargs,
|
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,
|
&code, &use_main_obmalloc,
|
||||||
&allow_fork, &allow_exec,
|
&allow_fork, &allow_exec,
|
||||||
&allow_threads, &allow_daemon_threads,
|
&allow_threads, &allow_daemon_threads,
|
||||||
&check_multi_interp_extensions,
|
&check_multi_interp_extensions,
|
||||||
&own_gil)) {
|
&gil)) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
if (use_main_obmalloc < 0) {
|
if (use_main_obmalloc < 0) {
|
||||||
|
@ -1466,8 +1466,8 @@ run_in_subinterp_with_config(PyObject *self, PyObject *args, PyObject *kwargs)
|
||||||
PyErr_SetString(PyExc_ValueError, "missing allow_threads");
|
PyErr_SetString(PyExc_ValueError, "missing allow_threads");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
if (own_gil < 0) {
|
if (gil < 0) {
|
||||||
PyErr_SetString(PyExc_ValueError, "missing own_gil");
|
PyErr_SetString(PyExc_ValueError, "missing gil");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
if (allow_daemon_threads < 0) {
|
if (allow_daemon_threads < 0) {
|
||||||
|
@ -1490,7 +1490,7 @@ run_in_subinterp_with_config(PyObject *self, PyObject *args, PyObject *kwargs)
|
||||||
.allow_threads = allow_threads,
|
.allow_threads = allow_threads,
|
||||||
.allow_daemon_threads = allow_daemon_threads,
|
.allow_daemon_threads = allow_daemon_threads,
|
||||||
.check_multi_interp_extensions = check_multi_interp_extensions,
|
.check_multi_interp_extensions = check_multi_interp_extensions,
|
||||||
.own_gil = own_gil,
|
.gil = gil,
|
||||||
};
|
};
|
||||||
PyStatus status = Py_NewInterpreterFromConfig(&substate, &config);
|
PyStatus status = Py_NewInterpreterFromConfig(&substate, &config);
|
||||||
if (PyStatus_Exception(status)) {
|
if (PyStatus_Exception(status)) {
|
||||||
|
|
|
@ -578,12 +578,14 @@ init_interp_settings(PyInterpreterState *interp,
|
||||||
interp->feature_flags |= Py_RTFLAGS_MULTI_INTERP_EXTENSIONS;
|
interp->feature_flags |= Py_RTFLAGS_MULTI_INTERP_EXTENSIONS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* We check "gil" in init_interp_create_gil(). */
|
||||||
|
|
||||||
return _PyStatus_OK();
|
return _PyStatus_OK();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static PyStatus
|
static PyStatus
|
||||||
init_interp_create_gil(PyThreadState *tstate, int own_gil)
|
init_interp_create_gil(PyThreadState *tstate, int gil)
|
||||||
{
|
{
|
||||||
PyStatus status;
|
PyStatus status;
|
||||||
|
|
||||||
|
@ -598,6 +600,15 @@ init_interp_create_gil(PyThreadState *tstate, int own_gil)
|
||||||
return status;
|
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 */
|
/* Create the GIL and take it */
|
||||||
status = _PyEval_InitGIL(tstate, own_gil);
|
status = _PyEval_InitGIL(tstate, own_gil);
|
||||||
if (_PyStatus_EXCEPTION(status)) {
|
if (_PyStatus_EXCEPTION(status)) {
|
||||||
|
@ -633,7 +644,7 @@ pycore_create_interpreter(_PyRuntimeState *runtime,
|
||||||
|
|
||||||
PyInterpreterConfig config = _PyInterpreterConfig_LEGACY_INIT;
|
PyInterpreterConfig config = _PyInterpreterConfig_LEGACY_INIT;
|
||||||
// The main interpreter always has its own GIL.
|
// The main interpreter always has its own GIL.
|
||||||
config.own_gil = 1;
|
config.gil = PyInterpreterConfig_OWN_GIL;
|
||||||
status = init_interp_settings(interp, &config);
|
status = init_interp_settings(interp, &config);
|
||||||
if (_PyStatus_EXCEPTION(status)) {
|
if (_PyStatus_EXCEPTION(status)) {
|
||||||
return status;
|
return status;
|
||||||
|
@ -647,7 +658,7 @@ pycore_create_interpreter(_PyRuntimeState *runtime,
|
||||||
// XXX For now we do this before the GIL is created.
|
// XXX For now we do this before the GIL is created.
|
||||||
(void) _PyThreadState_SwapNoGIL(tstate);
|
(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)) {
|
if (_PyStatus_EXCEPTION(status)) {
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
@ -2057,7 +2068,7 @@ new_interpreter(PyThreadState **tstate_p, const PyInterpreterConfig *config)
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
status = init_interp_create_gil(tstate, config->own_gil);
|
status = init_interp_create_gil(tstate, config->gil);
|
||||||
if (_PyStatus_EXCEPTION(status)) {
|
if (_PyStatus_EXCEPTION(status)) {
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue