diff -r 3ee5f02ef0f1 Lib/test/lock_tests.py --- a/Lib/test/lock_tests.py Sat Nov 07 09:26:07 2009 +0100 +++ b/Lib/test/lock_tests.py Mon Nov 09 12:59:05 2009 +0100 @@ -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): """ diff -r 3ee5f02ef0f1 Lib/test/test_threading.py --- a/Lib/test/test_threading.py Sat Nov 07 09:26:07 2009 +0100 +++ b/Lib/test/test_threading.py Mon Nov 09 12:59:05 2009 +0100 @@ -141,11 +141,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() diff -r 3ee5f02ef0f1 Lib/threading.py --- a/Lib/threading.py Sat Nov 07 09:26:07 2009 +0100 +++ b/Lib/threading.py Mon Nov 09 12:59:05 2009 +0100 @@ -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):