summaryrefslogtreecommitdiffstats
path: root/Modules
diff options
context:
space:
mode:
authorVictor Stinner <vstinner@python.org>2020-04-07 21:11:49 (GMT)
committerGitHub <noreply@github.com>2020-04-07 21:11:49 (GMT)
commit87255be6964979b5abdc4b9dcf81cdcfdad6e753 (patch)
tree30f3c5a680dd7ed6435841ecd38166de7654503e /Modules
parent48b069a003ba6c684a9ba78493fbbec5e89f10b8 (diff)
downloadcpython-87255be6964979b5abdc4b9dcf81cdcfdad6e753.zip
cpython-87255be6964979b5abdc4b9dcf81cdcfdad6e753.tar.gz
cpython-87255be6964979b5abdc4b9dcf81cdcfdad6e753.tar.bz2
bpo-40089: Add _at_fork_reinit() method to locks (GH-19195)
Add a private _at_fork_reinit() method to _thread.Lock, _thread.RLock, threading.RLock and threading.Condition classes: reinitialize the lock after fork in the child process; reset the lock to the unlocked state. Rename also the private _reset_internal_locks() method of threading.Event to _at_fork_reinit(). * Add _PyThread_at_fork_reinit() private function. It is excluded from the limited C API. * threading.Thread._reset_internal_locks() now calls _at_fork_reinit() on self._tstate_lock rather than creating a new Python lock object.
Diffstat (limited to 'Modules')
-rw-r--r--Modules/_threadmodule.c67
-rw-r--r--Modules/posixmodule.c3
2 files changed, 55 insertions, 15 deletions
diff --git a/Modules/_threadmodule.c b/Modules/_threadmodule.c
index bd8a40f..addef3e 100644
--- a/Modules/_threadmodule.c
+++ b/Modules/_threadmodule.c
@@ -213,6 +213,22 @@ lock_repr(lockobject *self)
self->locked ? "locked" : "unlocked", Py_TYPE(self)->tp_name, self);
}
+#ifdef HAVE_FORK
+static PyObject *
+lock__at_fork_reinit(lockobject *self, PyObject *Py_UNUSED(args))
+{
+ if (_PyThread_at_fork_reinit(&self->lock_lock) < 0) {
+ PyErr_SetString(ThreadError, "failed to reinitialize lock at fork");
+ return NULL;
+ }
+
+ self->locked = 0;
+
+ Py_RETURN_NONE;
+}
+#endif /* HAVE_FORK */
+
+
static PyMethodDef lock_methods[] = {
{"acquire_lock", (PyCFunction)(void(*)(void))lock_PyThread_acquire_lock,
METH_VARARGS | METH_KEYWORDS, acquire_doc},
@@ -230,6 +246,10 @@ static PyMethodDef lock_methods[] = {
METH_VARARGS | METH_KEYWORDS, acquire_doc},
{"__exit__", (PyCFunction)lock_PyThread_release_lock,
METH_VARARGS, release_doc},
+#ifdef HAVE_FORK
+ {"_at_fork_reinit", (PyCFunction)lock__at_fork_reinit,
+ METH_NOARGS, NULL},
+#endif
{NULL, NULL} /* sentinel */
};
@@ -446,22 +466,20 @@ For internal use by `threading.Condition`.");
static PyObject *
rlock_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
{
- rlockobject *self;
-
- self = (rlockobject *) type->tp_alloc(type, 0);
- if (self != NULL) {
- self->in_weakreflist = NULL;
- self->rlock_owner = 0;
- self->rlock_count = 0;
-
- self->rlock_lock = PyThread_allocate_lock();
- if (self->rlock_lock == NULL) {
- Py_DECREF(self);
- PyErr_SetString(ThreadError, "can't allocate lock");
- return NULL;
- }
+ rlockobject *self = (rlockobject *) type->tp_alloc(type, 0);
+ if (self == NULL) {
+ return NULL;
}
+ self->in_weakreflist = NULL;
+ self->rlock_owner = 0;
+ self->rlock_count = 0;
+ self->rlock_lock = PyThread_allocate_lock();
+ if (self->rlock_lock == NULL) {
+ Py_DECREF(self);
+ PyErr_SetString(ThreadError, "can't allocate lock");
+ return NULL;
+ }
return (PyObject *) self;
}
@@ -475,6 +493,23 @@ rlock_repr(rlockobject *self)
}
+#ifdef HAVE_FORK
+static PyObject *
+rlock__at_fork_reinit(rlockobject *self, PyObject *Py_UNUSED(args))
+{
+ if (_PyThread_at_fork_reinit(&self->rlock_lock) < 0) {
+ PyErr_SetString(ThreadError, "failed to reinitialize lock at fork");
+ return NULL;
+ }
+
+ self->rlock_owner = 0;
+ self->rlock_count = 0;
+
+ Py_RETURN_NONE;
+}
+#endif /* HAVE_FORK */
+
+
static PyMethodDef rlock_methods[] = {
{"acquire", (PyCFunction)(void(*)(void))rlock_acquire,
METH_VARARGS | METH_KEYWORDS, rlock_acquire_doc},
@@ -490,6 +525,10 @@ static PyMethodDef rlock_methods[] = {
METH_VARARGS | METH_KEYWORDS, rlock_acquire_doc},
{"__exit__", (PyCFunction)rlock_release,
METH_VARARGS, rlock_release_doc},
+#ifdef HAVE_FORK
+ {"_at_fork_reinit", (PyCFunction)rlock__at_fork_reinit,
+ METH_NOARGS, NULL},
+#endif
{NULL, NULL} /* sentinel */
};
diff --git a/Modules/posixmodule.c b/Modules/posixmodule.c
index 345798d..4264bf1 100644
--- a/Modules/posixmodule.c
+++ b/Modules/posixmodule.c
@@ -491,7 +491,8 @@ register_at_forker(PyObject **lst, PyObject *func)
}
return PyList_Append(*lst, func);
}
-#endif
+#endif /* HAVE_FORK */
+
/* Legacy wrapper */
void