[Python-checkins] r76175 - in python/branches/release31-maint: Lib/test/lock_tests.py Lib/test/test_thread.py Lib/test/test_threading.py Lib/threading.py Misc/NEWS

antoine.pitrou python-checkins at python.org
Mon Nov 9 17:52:47 CET 2009


Author: antoine.pitrou
Date: Mon Nov 9 17:52:46 2009
New Revision: 76175
Log:
Merged revisions 76138,76173 via svnmerge from 
svn+ssh://pythondev@svn.python.org/python/branches/py3k
................
 r76138 | antoine.pitrou | 2009年11月06日 23:41:14 +0100 (ven., 06 nov. 2009) | 10 lines
 
 Merged revisions 76137 via svnmerge from 
 svn+ssh://pythondev@svn.python.org/python/trunk
 
 ........
 r76137 | antoine.pitrou | 2009年11月06日 23:34:35 +0100 (ven., 06 nov. 2009) | 4 lines
 
 Issue #7270: Add some dedicated unit tests for multi-thread synchronization
 primitives such as Lock, RLock, Condition, Event and Semaphore.
 ........
................
 r76173 | antoine.pitrou | 2009年11月09日 17:08:16 +0100 (lun., 09 nov. 2009) | 11 lines
 
 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()`.
 ........
................
Added:
 python/branches/release31-maint/Lib/test/lock_tests.py
 - copied, changed from r76138, /python/branches/py3k/Lib/test/lock_tests.py
Modified:
 python/branches/release31-maint/ (props changed)
 python/branches/release31-maint/Lib/test/test_thread.py
 python/branches/release31-maint/Lib/test/test_threading.py
 python/branches/release31-maint/Lib/threading.py
 python/branches/release31-maint/Misc/NEWS
Copied: python/branches/release31-maint/Lib/test/lock_tests.py (from r76138, /python/branches/py3k/Lib/test/lock_tests.py)
==============================================================================
--- /python/branches/py3k/Lib/test/lock_tests.py	(original)
+++ python/branches/release31-maint/Lib/test/lock_tests.py	Mon Nov 9 17:52:46 2009
@@ -130,6 +130,19 @@
 # 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):
 """
Modified: python/branches/release31-maint/Lib/test/test_thread.py
==============================================================================
--- python/branches/release31-maint/Lib/test/test_thread.py	(original)
+++ python/branches/release31-maint/Lib/test/test_thread.py	Mon Nov 9 17:52:46 2009
@@ -5,6 +5,7 @@
 import _thread as thread
 import time
 
+from test import lock_tests
 
 NUMTASKS = 10
 NUMTRIPS = 3
@@ -161,8 +162,12 @@
 if finished:
 self.done_mutex.release()
 
+class LockTests(lock_tests.LockTests):
+ locktype = thread.allocate_lock
+
+
 def test_main():
- support.run_unittest(ThreadRunningTests, BarrierTest)
+ support.run_unittest(ThreadRunningTests, BarrierTest, LockTests)
 
 if __name__ == "__main__":
 test_main()
Modified: python/branches/release31-maint/Lib/test/test_threading.py
==============================================================================
--- python/branches/release31-maint/Lib/test/test_threading.py	(original)
+++ python/branches/release31-maint/Lib/test/test_threading.py	Mon Nov 9 17:52:46 2009
@@ -11,6 +11,8 @@
 import unittest
 import weakref
 
+from test import lock_tests
+
 # A trivial mutable counter.
 class Counter(object):
 def __init__(self):
@@ -133,11 +135,9 @@
 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()
@@ -471,22 +471,6 @@
 thread.start()
 self.assertRaises(RuntimeError, thread.start)
 
- def test_releasing_unacquired_rlock(self):
- rlock = threading.RLock()
- self.assertRaises(RuntimeError, rlock.release)
-
- def test_waiting_on_unacquired_condition(self):
- cond = threading.Condition()
- self.assertRaises(RuntimeError, cond.wait)
-
- def test_notify_on_unacquired_condition(self):
- cond = threading.Condition()
- self.assertRaises(RuntimeError, cond.notify)
-
- def test_semaphore_with_negative_value(self):
- self.assertRaises(ValueError, threading.Semaphore, value = -1)
- self.assertRaises(ValueError, threading.Semaphore, value = -sys.maxsize)
-
 def test_joining_current_thread(self):
 current_thread = threading.current_thread()
 self.assertRaises(RuntimeError, current_thread.join);
@@ -501,11 +485,37 @@
 self.assertRaises(RuntimeError, setattr, thread, "daemon", True)
 
 
+class LockTests(lock_tests.LockTests):
+ locktype = staticmethod(threading.Lock)
+
+class RLockTests(lock_tests.RLockTests):
+ locktype = staticmethod(threading.RLock)
+
+class EventTests(lock_tests.EventTests):
+ eventtype = staticmethod(threading.Event)
+
+class ConditionAsRLockTests(lock_tests.RLockTests):
+ # An Condition uses an RLock by default and exports its API.
+ locktype = staticmethod(threading.Condition)
+
+class ConditionTests(lock_tests.ConditionTests):
+ condtype = staticmethod(threading.Condition)
+
+class SemaphoreTests(lock_tests.SemaphoreTests):
+ semtype = staticmethod(threading.Semaphore)
+
+class BoundedSemaphoreTests(lock_tests.BoundedSemaphoreTests):
+ semtype = staticmethod(threading.BoundedSemaphore)
+
+
 def test_main():
- test.support.run_unittest(ThreadTests,
- ThreadJoinOnShutdown,
- ThreadingExceptionTests,
- )
+ test.support.run_unittest(LockTests, RLockTests, EventTests,
+ ConditionAsRLockTests, ConditionTests,
+ SemaphoreTests, BoundedSemaphoreTests,
+ ThreadTests,
+ ThreadJoinOnShutdown,
+ ThreadingExceptionTests,
+ )
 
 if __name__ == "__main__":
 test_main()
Modified: python/branches/release31-maint/Lib/threading.py
==============================================================================
--- python/branches/release31-maint/Lib/threading.py	(original)
+++ python/branches/release31-maint/Lib/threading.py	Mon Nov 9 17:52:46 2009
@@ -92,14 +92,16 @@
 
 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 @@
 __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 @@
 return (count, owner)
 
 def _is_owned(self):
- return self._owner is current_thread()
+ return self._owner == _get_ident()
 
 
 def Condition(*args, **kwargs):
Modified: python/branches/release31-maint/Misc/NEWS
==============================================================================
--- python/branches/release31-maint/Misc/NEWS	(original)
+++ python/branches/release31-maint/Misc/NEWS	Mon Nov 9 17:52:46 2009
@@ -40,6 +40,10 @@
 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.
 
@@ -140,6 +144,9 @@
 Tests
 -----
 
+- Issue #7270: Add some dedicated unit tests for multi-thread synchronization
+ primitives such as Lock, RLock, Condition, Event and Semaphore.
+
 - Issue #7248 (part 2): Use a unique temporary directory for importlib source
 tests instead of tempfile.tempdir. This prevents the tests from sharing state
 between concurrent executions on the same system.


More information about the Python-checkins mailing list

AltStyle によって変換されたページ (->オリジナル) /