8000 [3.13] gh-117721: use PyMutex in `_thread.lock` (#125110) (#125116) · python/cpython@20242a4 · GitHub
[go: up one dir, main page]

Skip to content

Commit 20242a4

Browse files
[3.13] gh-117721: use PyMutex in _thread.lock (#125110) (#125116)
* gh-117721: use PyMutex in `_thread.lock` (#125110) (cherry picked from commit fca5529)
1 parent 089c6d2 commit 20242a4

File tree

1 file changed

+10
-44
lines changed

1 file changed

+10
-44
lines changed

Modules/_threadmodule.c

Lines changed: 10 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -701,9 +701,7 @@ static PyType_Spec ThreadHandle_Type_spec = {
701701

702702
typedef struct {
703703
PyObject_HEAD
704-
PyThread_type_lock lock_lock;
705-
PyObject *in_weakreflist;
706-
char locked; /* for sanity checking */
704+
PyMutex lock;
707705
} lockobject;
708706

709707
static int
@@ -717,15 +715,7 @@ static void
717715
lock_dealloc(lockobject *self)
718716
{
719717
PyObject_GC_UnTrack(self);
720-
if (self->in_weakreflist != NULL) {
721-
PyObject_ClearWeakRefs((PyObject *) self);
722-
}
723-
if (self->lock_lock != NULL) {
724-
/* Unlock the lock so it's safe to free it */
725-
if (self->locked)
726-
PyThread_release_lock(self->lock_lock);
727-
PyThread_free_lock(self->lock_lock);
728-
}
718+
PyObject_ClearWeakRefs((PyObject *) self);
729719
PyTypeObject *tp = Py_TYPE(self);
730720
tp->tp_free((PyObject*)self);
731721
Py_DECREF(tp);
@@ -790,13 +780,12 @@ lock_PyThread_acquire_lock(lockobject *self, PyObject *args, PyObject *kwds)
790780
if (lock_acquire_parse_args(args, kwds, &timeout) < 0)
791781
return NULL;
792782

793-
PyLockStatus r = acquire_timed(self->lock_lock, timeout);
783+
PyLockStatus r = _PyMutex_LockTimed(&self->lock, timeout,
784+
_PY_LOCK_HANDLE_SIGNALS | _PY_LOCK_DETACH);
794785
if (r == PY_LOCK_INTR) {
795786
return NULL;
796787
}
797788

798-
if (r == PY_LOCK_ACQUIRED)
799-
self->locked = 1;
800789
return PyBool_FromLong(r == PY_LOCK_ACQUIRED);
801790
}
802791

@@ -827,13 +816,11 @@ static PyObject *
827816
lock_PyThread_release_lock(lockobject *self, PyObject *Py_UNUSED(ignored))
828817
{
829818
/* Sanity check: the lock must be locked */
830-
if (!self->locked) {
819+
if (_PyMutex_TryUnlock(&self->lock) < 0) {
831820
PyErr_SetString(ThreadError, "release unlocked lock");
832821
return NULL;
833822
}
834823

835-
self->locked = 0;
836-
PyThread_release_lock(self->lock_lock);
837824
Py_RETURN_NONE;
838825
}
839826

@@ -860,7 +847,7 @@ Release the lock.");
860847
static PyObject *
861848
lock_locked_lock(lockobject *self, PyObject *Py_UNUSED(ignored))
862849
{
863-
return PyBool_FromLong((long)self->locked);
850+
return PyBool_FromLong(PyMutex_IsLocked(&self->lock));
864851
}
865852

866853
PyDoc_STRVAR(locked_doc,
@@ -879,20 +866,14 @@ static PyObject *
879866
lock_repr(lockobject *self)
880867
{
881868
return PyUnicode_FromFormat("<%s %s object at %p>",
882-
self->locked ? "locked" : "unlocked", Py_TYPE(self)->tp_name, self);
869+
PyMutex_IsLocked(&self->lock) ? "locked" : "unlocked", Py_TYPE(self)->tp_name, self);
883870
}
884871

885872
#ifdef HAVE_FORK
886873
static PyObject *
887874
lock__at_fork_reinit(lockobject *self, PyObject *Py_UNUSED(args))
888875
{
889-
if (_PyThread_at_fork_reinit(&self->lock_lock) < 0) {
890-
PyErr_SetString(ThreadError, "failed to reinitialize lock at fork");
891-
return NULL;
892-
}
893-
894-
self->locked = 0;
895-
876+
_PyMutex_at_fork_reinit(&self->lock);
896877
Py_RETURN_NONE;
897878
}
898879
#endif /* HAVE_FORK */
@@ -958,18 +939,12 @@ A lock is not owned by the thread that locked it; another thread may\n\
958939
unlock it. A thread attempting to lock a lock that it has already locked\n\
959940
will block until another thread unlocks it. Deadlocks may ensue.");
960941

961-
static PyMemberDef lock_type_members[] = {
962-
{"__weaklistoffset__", Py_T_PYSSIZET, offsetof(lockobject, in_weakreflist), Py_READONLY},
963-
{NULL},
964-
};
965-
966942
static PyType_Slot lock_type_slots[] = {
967943
{Py_tp_dealloc, (destructor)lock_dealloc},
968944
{Py_tp_repr, (reprfunc)lock_repr},
969945
{Py_tp_doc, (void *)lock_doc},
970946
{Py_tp_methods, lock_methods},
971947
{Py_tp_traverse, lock_traverse},
972-
{Py_tp_members, lock_type_members},
973948
{Py_tp_new, lock_new},
974949
{0, 0}
975950
};
@@ -978,7 +953,7 @@ static PyType_Spec lock_type_spec = {
978953
.name = "_thread.lock",
979954
.basicsize = sizeof(lockobject),
980955
.flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
981-
Py_TPFLAGS_IMMUTABLETYPE),
956+
Py_TPFLAGS_IMMUTABLETYPE | Py_TPFLAGS_MANAGED_WEAKREF),
982957
.slots = lock_type_slots,
983958
};
984959

@@ -1320,16 +1295,7 @@ newlockobject(PyObject *module)
13201295
if (self == NULL) {
13211296
return NULL;
13221297
}
1323-
1324-
self->lock_lock = PyThread_allocate_lock();
1325-
self->locked = 0;
1326-
self->in_weakreflist = NULL;
1327-
1328-
if (self->lock_lock == NULL) {
1329-
Py_DECREF(self);
1330-
PyErr_SetString(ThreadError, "can't allocate lock");
1331-
return NULL;
1332-
}
1298+
self->lock = (PyMutex){0};
13331299
return self;
13341300
}
13351301

0 commit comments

Comments
 (0)
0