Kaydet (Commit) d7158d4c authored tarafından Antoine Pitrou's avatar Antoine Pitrou

Issue #7282: Fix a memory leak when an RLock was used in a thread other

than those started through `threading.Thread` (for example, using
`thread.start_new_thread()`.
üst d19915ed
......@@ -130,6 +130,19 @@ class BaseLockTests(BaseTestCase):
# Check the lock is unacquired
Bunch(f, 1).wait_for_finished()
def test_thread_leak(self):
# The lock shouldn't leak a Thread instance when used from a foreign
# (non-threading) thread.
lock = self.locktype()
def f():
lock.acquire()
lock.release()
n = len(threading.enumerate())
# We run many threads in the hope that existing threads ids won't
# be recycled.
Bunch(f, 15).wait_for_finished()
self.assertEqual(n, len(threading.enumerate()))
class LockTests(BaseLockTests):
"""
......
......@@ -143,11 +143,9 @@ class ThreadTests(BaseTestCase):
def test_foreign_thread(self):
# Check that a "foreign" thread can use the threading module.
def f(mutex):
# Acquiring an RLock forces an entry for the foreign
# Calling current_thread() forces an entry for the foreign
# thread to get made in the threading._active map.
r = threading.RLock()
r.acquire()
r.release()
threading.current_thread()
mutex.release()
mutex = threading.Lock()
......
......@@ -106,14 +106,16 @@ class _RLock(_Verbose):
def __repr__(self):
owner = self.__owner
return "<%s(%s, %d)>" % (
self.__class__.__name__,
owner and owner.name,
self.__count)
try:
owner = _active[owner].name
except KeyError:
pass
return "<%s owner=%r count=%d>" % (
self.__class__.__name__, owner, self.__count)
def acquire(self, blocking=1):
me = current_thread()
if self.__owner is me:
me = _get_ident()
if self.__owner == me:
self.__count = self.__count + 1
if __debug__:
self._note("%s.acquire(%s): recursive success", self, blocking)
......@@ -132,7 +134,7 @@ class _RLock(_Verbose):
__enter__ = acquire
def release(self):
if self.__owner is not current_thread():
if self.__owner != _get_ident():
raise RuntimeError("cannot release un-acquired lock")
self.__count = count = self.__count - 1
if not count:
......@@ -168,7 +170,7 @@ class _RLock(_Verbose):
return (count, owner)
def _is_owned(self):
return self.__owner is current_thread()
return self.__owner == _get_ident()
def Condition(*args, **kwargs):
......
......@@ -426,6 +426,10 @@ Core and Builtins
Library
-------
- Issue #7282: Fix a memory leak when an RLock was used in a thread other
than those started through `threading.Thread` (for example, using
`thread.start_new_thread()`.
- Issue #7264: Fix a possible deadlock when deallocating thread-local objects
which are part of a reference cycle.
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment