Skip to content

Commit 3effede

Browse files
gh-134323: Fix the new threading.RLock.locked method (#134368)
Co-authored-by: Kumar Aditya <kumaraditya@python.org>
1 parent bd4046f commit 3effede

File tree

4 files changed

+29
-4
lines changed

4 files changed

+29
-4
lines changed

Lib/test/lock_tests.py

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -370,6 +370,24 @@ def test_locked(self):
370370
lock.release()
371371
self.assertFalse(lock.locked())
372372

373+
def test_locked_with_2threads(self):
374+
# see gh-134323: check that a rlock which
375+
# is acquired in a different thread,
376+
# is still locked in the main thread.
377+
result = []
378+
rlock = self.locktype()
379+
self.assertFalse(rlock.locked())
380+
def acquire():
381+
result.append(rlock.locked())
382+
rlock.acquire()
383+
result.append(rlock.locked())
384+
385+
with Bunch(acquire, 1):
386+
pass
387+
self.assertTrue(rlock.locked())
388+
self.assertFalse(result[0])
389+
self.assertTrue(result[1])
390+
373391
def test_release_save_unacquired(self):
374392
# Cannot _release_save an unacquired lock
375393
lock = self.locktype()

Lib/threading.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -158,7 +158,7 @@ def __repr__(self):
158158
except KeyError:
159159
pass
160160
return "<%s %s.%s object owner=%r count=%d at %s>" % (
161-
"locked" if self._block.locked() else "unlocked",
161+
"locked" if self.locked() else "unlocked",
162162
self.__class__.__module__,
163163
self.__class__.__qualname__,
164164
owner,
@@ -237,7 +237,7 @@ def __exit__(self, t, v, tb):
237237

238238
def locked(self):
239239
"""Return whether this object is locked."""
240-
return self._count > 0
240+
return self._block.locked()
241241

242242
# Internal methods used by condition variables
243243

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Fix the :meth:`threading.RLock.locked` method.

Modules/_threadmodule.c

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1022,6 +1022,11 @@ rlock_traverse(PyObject *self, visitproc visit, void *arg)
10221022
return 0;
10231023
}
10241024

1025+
static int
1026+
rlock_locked_impl(rlockobject *self)
1027+
{
1028+
return PyMutex_IsLocked(&self->lock.mutex);
1029+
}
10251030

10261031
static void
10271032
rlock_dealloc(PyObject *self)
@@ -1111,7 +1116,7 @@ static PyObject *
11111116
rlock_locked(PyObject *op, PyObject *Py_UNUSED(ignored))
11121117
{
11131118
rlockobject *self = rlockobject_CAST(op);
1114-
int is_locked = _PyRecursiveMutex_IsLockedByCurrentThread(&self->lock);
1119+
int is_locked = rlock_locked_impl(self);
11151120
return PyBool_FromLong(is_locked);
11161121
}
11171122

@@ -1219,10 +1224,11 @@ rlock_repr(PyObject *op)
12191224
{
12201225
rlockobject *self = rlockobject_CAST(op);
12211226
PyThread_ident_t owner = self->lock.thread;
1227+
int locked = rlock_locked_impl(self);
12221228
size_t count = self->lock.level + 1;
12231229
return PyUnicode_FromFormat(
12241230
"<%s %s object owner=%" PY_FORMAT_THREAD_IDENT_T " count=%zu at %p>",
1225-
owner ? "locked" : "unlocked",
1231+
locked ? "locked" : "unlocked",
12261232
Py_TYPE(self)->tp_name, owner,
12271233
count, self);
12281234
}

0 commit comments

Comments
 (0)