Merged revisions 76172 via svnmerge from
svn+ssh://pythondev@svn.python.org/python/trunk ........ r76172 | antoine.pitrou | 2009-11-09 17:00:11 +0100 (lun., 09 nov. 2009) | 5 lines 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()`. ........
This commit is contained in:
parent
3c573af162
commit
b087268217
|
@ -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()
|
||||
|
|
|
@ -92,14 +92,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=True):
|
||||
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)
|
||||
|
@ -118,7 +120,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:
|
||||
|
@ -152,7 +154,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):
|
||||
|
|
|
@ -123,6 +123,10 @@ C-API
|
|||
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 #7187: Importlib would not silence the IOError raised when trying to
|
||||
write new bytecode when it was made read-only.
|
||||
|
||||
|
|
Loading…
Reference in New Issue