gh-116322: Enable the GIL while loading C extension modules by swtaarrs · Pull Request #118560 · python/cpython · GitHub
Skip to content
47 changes: 46 additions & 1 deletion Include/internal/pycore_ceval.h
16 changes: 14 additions & 2 deletions Include/internal/pycore_gil.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,20 @@ extern "C" {

struct _gil_runtime_state {
#ifdef Py_GIL_DISABLED
/* Whether or not this GIL is being used. Can change from 0 to 1 at runtime
if, for example, a module that requires the GIL is loaded. */
/* If this GIL is disabled, enabled == 0.

If this GIL is enabled transiently (most likely to initialize a module
of unknown safety), enabled indicates the number of active transient
requests.

If this GIL is enabled permanently, enabled == INT_MAX.

It must not be modified directly; use _PyEval_EnableGILTransiently(),
_PyEval_EnableGILPermanently(), and _PyEval_DisableGIL()

It is always read and written atomically, but a thread can assume its
value will be stable as long as that thread is attached or knows that no
other threads are attached (e.g., during a stop-the-world.). */
int enabled;
#endif
/* microseconds (the Python API uses seconds, though) */
Expand Down
13 changes: 13 additions & 0 deletions Include/internal/pycore_import.h
Original file line number Diff line number Diff line change
Expand Up @@ -206,6 +206,19 @@ extern int _PyImport_CheckSubinterpIncompatibleExtensionAllowed(
// Export for '_testinternalcapi' shared extension
PyAPI_FUNC(int) _PyImport_ClearExtension(PyObject *name, PyObject *filename);

#ifdef Py_GIL_DISABLED
// Assuming that the GIL is enabled from a call to
// _PyEval_EnableGILTransient(), resolve the transient request depending on the
// state of the module argument:
// - If module is NULL or a PyModuleObject with md_gil == Py_MOD_GIL_NOT_USED,
// call _PyEval_DisableGIL().
// - Otherwise, call _PyEval_EnableGILPermanent(). If the GIL was not already
// enabled permanently, issue a warning referencing the module's name.
//
// This function may raise an exception.
extern int _PyImport_CheckGILForModule(PyObject *module, PyObject *module_name);
#endif

#ifdef __cplusplus
}
#endif
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
In ``--disable-gil`` builds, the GIL will be enabled while loading C extension modules. If the module indicates that it supports running without the GIL, the GIL will be disabled once loading is complete. Otherwise, the GIL will remain enabled for the remainder of the interpreter's lifetime. This behavior does not apply if the GIL has been explicitly enabled or disabled with ``PYTHON_GIL`` or ``-Xgil``.
12 changes: 9 additions & 3 deletions PC/_wmimodule.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -362,12 +362,18 @@ static PyMethodDef wmi_functions[] = {
{ NULL, NULL, 0, NULL }
};

static PyModuleDef_Slot wmi_slots[] = {
{Py_mod_gil, Py_MOD_GIL_NOT_USED},
{0, NULL},
};

static PyModuleDef wmi_def = {
PyModuleDef_HEAD_INIT,
"_wmi",
NULL, // doc
0, // m_size
wmi_functions
NULL, // doc
0, // m_size
wmi_functions, // m_methods
wmi_slots, // m_slots
};

extern "C" {
Expand Down
158 changes: 145 additions & 13 deletions Python/ceval_gil.c
Loading