diff options
-rw-r--r-- | Include/cpython/initconfig.h | 10 | ||||
-rw-r--r-- | Lib/test/support/__init__.py | 5 | ||||
-rw-r--r-- | Lib/test/test_import/__init__.py | 3 | ||||
-rw-r--r-- | Misc/NEWS.d/next/C API/2023-06-09-19-16-57.gh-issue-105603.-z6G22.rst | 5 | ||||
-rw-r--r-- | Modules/_testcapimodule.c | 14 | ||||
-rw-r--r-- | Python/pylifecycle.c | 19 |
6 files changed, 40 insertions, 16 deletions
diff --git a/Include/cpython/initconfig.h b/Include/cpython/initconfig.h index efae240..c103c20 100644 --- a/Include/cpython/initconfig.h +++ b/Include/cpython/initconfig.h @@ -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; @@ -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 \ @@ -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 \ @@ -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 --------------------------------------- */ diff --git a/Lib/test/support/__init__.py b/Lib/test/support/__init__.py index 4d01bb5..c59508b 100644 --- a/Lib/test/support/__init__.py +++ b/Lib/test/support/__init__.py @@ -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) diff --git a/Lib/test/test_import/__init__.py b/Lib/test/test_import/__init__.py index 227c912..71a50bc 100644 --- a/Lib/test/test_import/__init__.py +++ b/Lib/test/test_import/__init__.py @@ -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): diff --git a/Misc/NEWS.d/next/C API/2023-06-09-19-16-57.gh-issue-105603.-z6G22.rst b/Misc/NEWS.d/next/C API/2023-06-09-19-16-57.gh-issue-105603.-z6G22.rst new file mode 100644 index 0000000..cd3d9bc --- /dev/null +++ b/Misc/NEWS.d/next/C API/2023-06-09-19-16-57.gh-issue-105603.-z6G22.rst @@ -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". diff --git a/Modules/_testcapimodule.c b/Modules/_testcapimodule.c index b8ad00a..04a8800 100644 --- a/Modules/_testcapimodule.c +++ b/Modules/_testcapimodule.c @@ -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 */ @@ -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) { @@ -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) { @@ -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)) { diff --git a/Python/pylifecycle.c b/Python/pylifecycle.c index 95b39f4..c4e6b69 100644 --- a/Python/pylifecycle.c +++ b/Python/pylifecycle.c @@ -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; @@ -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)) { @@ -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; @@ -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; } @@ -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; } |