aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/Modules/_threadmodule.c
diff options
context:
space:
mode:
Diffstat (limited to 'Modules/_threadmodule.c')
-rw-r--r--Modules/_threadmodule.c24
1 files changed, 21 insertions, 3 deletions
diff --git a/Modules/_threadmodule.c b/Modules/_threadmodule.c
index 77286ed2a74..cc83be4b5ff 100644
--- a/Modules/_threadmodule.c
+++ b/Modules/_threadmodule.c
@@ -296,6 +296,12 @@ _PyThread_AfterFork(struct _pythread_runtime_state *state)
continue;
}
+ // Keep handles for threads that have not been started yet. They are
+ // safe to start in the child process.
+ if (handle->state == THREAD_HANDLE_NOT_STARTED) {
+ continue;
+ }
+
// Mark all threads as done. Any attempts to join or detach the
// underlying OS thread (if any) could crash. We are the only thread;
// it's safe to set this non-atomically.
@@ -1022,6 +1028,11 @@ rlock_traverse(PyObject *self, visitproc visit, void *arg)
return 0;
}
+static int
+rlock_locked_impl(rlockobject *self)
+{
+ return PyMutex_IsLocked(&self->lock.mutex);
+}
static void
rlock_dealloc(PyObject *self)
@@ -1111,7 +1122,7 @@ static PyObject *
rlock_locked(PyObject *op, PyObject *Py_UNUSED(ignored))
{
rlockobject *self = rlockobject_CAST(op);
- int is_locked = _PyRecursiveMutex_IsLockedByCurrentThread(&self->lock);
+ int is_locked = rlock_locked_impl(self);
return PyBool_FromLong(is_locked);
}
@@ -1219,10 +1230,17 @@ rlock_repr(PyObject *op)
{
rlockobject *self = rlockobject_CAST(op);
PyThread_ident_t owner = self->lock.thread;
- size_t count = self->lock.level + 1;
+ int locked = rlock_locked_impl(self);
+ size_t count;
+ if (locked) {
+ count = self->lock.level + 1;
+ }
+ else {
+ count = 0;
+ }
return PyUnicode_FromFormat(
"<%s %s object owner=%" PY_FORMAT_THREAD_IDENT_T " count=%zu at %p>",
- owner ? "locked" : "unlocked",
+ locked ? "locked" : "unlocked",
Py_TYPE(self)->tp_name, owner,
count, self);
}