Skip to content

Commit c2824d4

Browse files
author
Victor Stinner
committed
Issue #11915: threading.RLock()._release_save() raises a RuntimeError if the
lock was not acquired.
1 parent a82aa55 commit c2824d4

File tree

4 files changed

+13
-0
lines changed

4 files changed

+13
-0
lines changed

Lib/test/lock_tests.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -247,13 +247,15 @@ def test_release_unacquired(self):
247247
# Cannot release an unacquired lock
248248
lock = self.locktype()
249249
self.assertRaises(RuntimeError, lock.release)
250+
self.assertRaises(RuntimeError, lock._release_save)
250251
lock.acquire()
251252
lock.acquire()
252253
lock.release()
253254
lock.acquire()
254255
lock.release()
255256
lock.release()
256257
self.assertRaises(RuntimeError, lock.release)
258+
self.assertRaises(RuntimeError, lock._release_save)
257259

258260
def test_different_thread(self):
259261
# Cannot release from a different thread

Lib/threading.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -157,6 +157,8 @@ def _acquire_restore(self, state):
157157
def _release_save(self):
158158
if __debug__:
159159
self._note("%s._release_save()", self)
160+
if self._count == 0:
161+
raise RuntimeError("cannot release un-acquired lock")
160162
count = self._count
161163
self._count = 0
162164
owner = self._owner

Misc/NEWS

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,9 @@ Core and Builtins
113113
Library
114114
-------
115115

116+
- Issue #11915: threading.RLock()._release_save() raises a RuntimeError if the
117+
lock was not acquired.
118+
116119
- Issue #11258: Speed up ctypes.util.find_library() under Linux by a factor
117120
of 5 to 10. Initial patch by Jonas H.
118121

Modules/_threadmodule.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -414,6 +414,12 @@ rlock_release_save(rlockobject *self)
414414
long owner;
415415
unsigned long count;
416416

417+
if (self->rlock_count == 0) {
418+
PyErr_SetString(PyExc_RuntimeError,
419+
"cannot release un-acquired lock");
420+
return NULL;
421+
}
422+
417423
owner = self->rlock_owner;
418424
count = self->rlock_count;
419425
self->rlock_count = 0;

0 commit comments

Comments
 (0)