bpo-1635741: Port _posixsubprocess module to multiphase init (GH-23406)
This commit is contained in:
parent
ed1007c0d7
commit
035deee265
|
@ -0,0 +1 @@
|
||||||
|
Port _posixshmem extension module to multiphase initialization (:pep:`489`).
|
|
@ -85,11 +85,9 @@ get_posixsubprocess_state(PyObject *module)
|
||||||
return (_posixsubprocessstate *)state;
|
return (_posixsubprocessstate *)state;
|
||||||
}
|
}
|
||||||
|
|
||||||
#define _posixsubprocessstate_global get_posixsubprocess_state(PyState_FindModule(&_posixsubprocessmodule))
|
|
||||||
|
|
||||||
/* If gc was disabled, call gc.enable(). Ignore errors. */
|
/* If gc was disabled, call gc.enable(). Ignore errors. */
|
||||||
static void
|
static void
|
||||||
_enable_gc(int need_to_reenable_gc, PyObject *gc_module)
|
_enable_gc(int need_to_reenable_gc, PyObject *gc_module, _posixsubprocessstate *state)
|
||||||
{
|
{
|
||||||
PyObject *result;
|
PyObject *result;
|
||||||
PyObject *exctype, *val, *tb;
|
PyObject *exctype, *val, *tb;
|
||||||
|
@ -97,7 +95,7 @@ _enable_gc(int need_to_reenable_gc, PyObject *gc_module)
|
||||||
if (need_to_reenable_gc) {
|
if (need_to_reenable_gc) {
|
||||||
PyErr_Fetch(&exctype, &val, &tb);
|
PyErr_Fetch(&exctype, &val, &tb);
|
||||||
result = PyObject_CallMethodNoArgs(
|
result = PyObject_CallMethodNoArgs(
|
||||||
gc_module, _posixsubprocessstate_global->enable);
|
gc_module, state->enable);
|
||||||
if (result == NULL) {
|
if (result == NULL) {
|
||||||
/* We might have created a child process at this point, we
|
/* We might have created a child process at this point, we
|
||||||
* we have no good way to handle a failure to reenable GC
|
* we have no good way to handle a failure to reenable GC
|
||||||
|
@ -758,7 +756,7 @@ do_fork_exec(char *const exec_array[],
|
||||||
|
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
subprocess_fork_exec(PyObject* self, PyObject *args)
|
subprocess_fork_exec(PyObject *module, PyObject *args)
|
||||||
{
|
{
|
||||||
PyObject *gc_module = NULL;
|
PyObject *gc_module = NULL;
|
||||||
PyObject *executable_list, *py_fds_to_keep;
|
PyObject *executable_list, *py_fds_to_keep;
|
||||||
|
@ -782,6 +780,7 @@ subprocess_fork_exec(PyObject* self, PyObject *args)
|
||||||
Py_ssize_t arg_num, num_groups = 0;
|
Py_ssize_t arg_num, num_groups = 0;
|
||||||
int need_after_fork = 0;
|
int need_after_fork = 0;
|
||||||
int saved_errno = 0;
|
int saved_errno = 0;
|
||||||
|
_posixsubprocessstate *state = get_posixsubprocess_state(module);
|
||||||
|
|
||||||
if (!PyArg_ParseTuple(
|
if (!PyArg_ParseTuple(
|
||||||
args, "OOpO!OOiiiiiiiiiiOOOiO:fork_exec",
|
args, "OOpO!OOiiiiiiiiiiOOOiO:fork_exec",
|
||||||
|
@ -827,7 +826,7 @@ subprocess_fork_exec(PyObject* self, PyObject *args)
|
||||||
if (gc_module == NULL)
|
if (gc_module == NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
result = PyObject_CallMethodNoArgs(
|
result = PyObject_CallMethodNoArgs(
|
||||||
gc_module, _posixsubprocessstate_global->isenabled);
|
gc_module, state->isenabled);
|
||||||
if (result == NULL) {
|
if (result == NULL) {
|
||||||
Py_DECREF(gc_module);
|
Py_DECREF(gc_module);
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -839,7 +838,7 @@ subprocess_fork_exec(PyObject* self, PyObject *args)
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
result = PyObject_CallMethodNoArgs(
|
result = PyObject_CallMethodNoArgs(
|
||||||
gc_module, _posixsubprocessstate_global->disable);
|
gc_module, state->disable);
|
||||||
if (result == NULL) {
|
if (result == NULL) {
|
||||||
Py_DECREF(gc_module);
|
Py_DECREF(gc_module);
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -1073,7 +1072,7 @@ cleanup:
|
||||||
if (exec_array)
|
if (exec_array)
|
||||||
_Py_FreeCharPArray(exec_array);
|
_Py_FreeCharPArray(exec_array);
|
||||||
|
|
||||||
_enable_gc(need_to_reenable_gc, gc_module);
|
_enable_gc(need_to_reenable_gc, gc_module, state);
|
||||||
Py_XDECREF(gc_module);
|
Py_XDECREF(gc_module);
|
||||||
|
|
||||||
return pid == -1 ? NULL : PyLong_FromPid(pid);
|
return pid == -1 ? NULL : PyLong_FromPid(pid);
|
||||||
|
@ -1113,12 +1112,38 @@ Raises: Only on an error in the parent process.\n\
|
||||||
PyDoc_STRVAR(module_doc,
|
PyDoc_STRVAR(module_doc,
|
||||||
"A POSIX helper for the subprocess module.");
|
"A POSIX helper for the subprocess module.");
|
||||||
|
|
||||||
|
static int
|
||||||
|
_posixsubprocess_exec(PyObject *module)
|
||||||
|
{
|
||||||
|
_posixsubprocessstate *state = get_posixsubprocess_state(module);
|
||||||
|
|
||||||
|
state->disable = PyUnicode_InternFromString("disable");
|
||||||
|
if (state->disable == NULL) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
state->enable = PyUnicode_InternFromString("enable");
|
||||||
|
if (state->enable == NULL) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
state->isenabled = PyUnicode_InternFromString("isenabled");
|
||||||
|
if (state->isenabled == NULL) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static PyMethodDef module_methods[] = {
|
static PyMethodDef module_methods[] = {
|
||||||
{"fork_exec", subprocess_fork_exec, METH_VARARGS, subprocess_fork_exec_doc},
|
{"fork_exec", subprocess_fork_exec, METH_VARARGS, subprocess_fork_exec_doc},
|
||||||
{NULL, NULL} /* sentinel */
|
{NULL, NULL} /* sentinel */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static PyModuleDef_Slot _posixsubprocess_slots[] = {
|
||||||
|
{Py_mod_exec, _posixsubprocess_exec},
|
||||||
|
{0, NULL}
|
||||||
|
};
|
||||||
|
|
||||||
static int _posixsubprocess_traverse(PyObject *m, visitproc visit, void *arg) {
|
static int _posixsubprocess_traverse(PyObject *m, visitproc visit, void *arg) {
|
||||||
Py_VISIT(get_posixsubprocess_state(m)->disable);
|
Py_VISIT(get_posixsubprocess_state(m)->disable);
|
||||||
|
@ -1140,36 +1165,18 @@ static void _posixsubprocess_free(void *m) {
|
||||||
|
|
||||||
static struct PyModuleDef _posixsubprocessmodule = {
|
static struct PyModuleDef _posixsubprocessmodule = {
|
||||||
PyModuleDef_HEAD_INIT,
|
PyModuleDef_HEAD_INIT,
|
||||||
"_posixsubprocess",
|
.m_name = "_posixsubprocess",
|
||||||
module_doc,
|
.m_doc = module_doc,
|
||||||
sizeof(_posixsubprocessstate),
|
.m_size = sizeof(_posixsubprocessstate),
|
||||||
module_methods,
|
.m_methods = module_methods,
|
||||||
NULL,
|
.m_slots = _posixsubprocess_slots,
|
||||||
_posixsubprocess_traverse,
|
.m_traverse = _posixsubprocess_traverse,
|
||||||
_posixsubprocess_clear,
|
.m_clear = _posixsubprocess_clear,
|
||||||
_posixsubprocess_free,
|
.m_free = _posixsubprocess_free,
|
||||||
};
|
};
|
||||||
|
|
||||||
PyMODINIT_FUNC
|
PyMODINIT_FUNC
|
||||||
PyInit__posixsubprocess(void)
|
PyInit__posixsubprocess(void)
|
||||||
{
|
{
|
||||||
PyObject* m;
|
return PyModuleDef_Init(&_posixsubprocessmodule);
|
||||||
|
|
||||||
m = PyState_FindModule(&_posixsubprocessmodule);
|
|
||||||
if (m != NULL) {
|
|
||||||
Py_INCREF(m);
|
|
||||||
return m;
|
|
||||||
}
|
|
||||||
|
|
||||||
m = PyModule_Create(&_posixsubprocessmodule);
|
|
||||||
if (m == NULL) {
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
get_posixsubprocess_state(m)->disable = PyUnicode_InternFromString("disable");
|
|
||||||
get_posixsubprocess_state(m)->enable = PyUnicode_InternFromString("enable");
|
|
||||||
get_posixsubprocess_state(m)->isenabled = PyUnicode_InternFromString("isenabled");
|
|
||||||
|
|
||||||
PyState_AddModule(m, &_posixsubprocessmodule);
|
|
||||||
return m;
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue