summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Include/cpython/initconfig.h10
-rw-r--r--Lib/test/support/__init__.py5
-rw-r--r--Lib/test/test_import/__init__.py3
-rw-r--r--Misc/NEWS.d/next/C API/2023-06-09-19-16-57.gh-issue-105603.-z6G22.rst5
-rw-r--r--Modules/_testcapimodule.c14
-rw-r--r--Python/pylifecycle.c19
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;
}