[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:
Miss Islington (bot) 2023-06-13 10:42:56 -07:00 committed by GitHub
parent 9c51ea5d55
commit c3a2cbb54d
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 40 additions and 16 deletions

View file

@ -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 --------------------------------------- */

View file

@ -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)

View file

@ -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):

View file

@ -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".

View file

@ -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)) {

View file

@ -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;
} }