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

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()`.
  ........
................
üst 536d299c
This diff is collapsed.
...@@ -5,6 +5,7 @@ from test import support ...@@ -5,6 +5,7 @@ from test import support
import _thread as thread import _thread as thread
import time import time
from test import lock_tests
NUMTASKS = 10 NUMTASKS = 10
NUMTRIPS = 3 NUMTRIPS = 3
...@@ -161,8 +162,12 @@ class BarrierTest(BasicThreadTest): ...@@ -161,8 +162,12 @@ class BarrierTest(BasicThreadTest):
if finished: if finished:
self.done_mutex.release() self.done_mutex.release()
class LockTests(lock_tests.LockTests):
locktype = thread.allocate_lock
def test_main(): def test_main():
support.run_unittest(ThreadRunningTests, BarrierTest) support.run_unittest(ThreadRunningTests, BarrierTest, LockTests)
if __name__ == "__main__": if __name__ == "__main__":
test_main() test_main()
...@@ -11,6 +11,8 @@ import time ...@@ -11,6 +11,8 @@ import time
import unittest import unittest
import weakref import weakref
from test import lock_tests
# A trivial mutable counter. # A trivial mutable counter.
class Counter(object): class Counter(object):
def __init__(self): def __init__(self):
...@@ -133,11 +135,9 @@ class ThreadTests(unittest.TestCase): ...@@ -133,11 +135,9 @@ class ThreadTests(unittest.TestCase):
def test_foreign_thread(self): def test_foreign_thread(self):
# Check that a "foreign" thread can use the threading module. # Check that a "foreign" thread can use the threading module.
def f(mutex): 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. # thread to get made in the threading._active map.
r = threading.RLock() threading.current_thread()
r.acquire()
r.release()
mutex.release() mutex.release()
mutex = threading.Lock() mutex = threading.Lock()
...@@ -471,22 +471,6 @@ class ThreadingExceptionTests(unittest.TestCase): ...@@ -471,22 +471,6 @@ class ThreadingExceptionTests(unittest.TestCase):
thread.start() thread.start()
self.assertRaises(RuntimeError, 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): def test_joining_current_thread(self):
current_thread = threading.current_thread() current_thread = threading.current_thread()
self.assertRaises(RuntimeError, current_thread.join); self.assertRaises(RuntimeError, current_thread.join);
...@@ -501,11 +485,37 @@ class ThreadingExceptionTests(unittest.TestCase): ...@@ -501,11 +485,37 @@ class ThreadingExceptionTests(unittest.TestCase):
self.assertRaises(RuntimeError, setattr, thread, "daemon", True) 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(): def test_main():
test.support.run_unittest(ThreadTests, test.support.run_unittest(LockTests, RLockTests, EventTests,
ThreadJoinOnShutdown, ConditionAsRLockTests, ConditionTests,
ThreadingExceptionTests, SemaphoreTests, BoundedSemaphoreTests,
) ThreadTests,
ThreadJoinOnShutdown,
ThreadingExceptionTests,
)
if __name__ == "__main__": if __name__ == "__main__":
test_main() test_main()
...@@ -92,14 +92,16 @@ class _RLock(_Verbose): ...@@ -92,14 +92,16 @@ class _RLock(_Verbose):
def __repr__(self): def __repr__(self):
owner = self._owner owner = self._owner
return "<%s(%s, %d)>" % ( try:
self.__class__.__name__, owner = _active[owner].name
owner and owner.name, except KeyError:
self._count) pass
return "<%s owner=%r count=%d>" % (
self.__class__.__name__, owner, self._count)
def acquire(self, blocking=True): def acquire(self, blocking=True):
me = current_thread() me = _get_ident()
if self._owner is me: if self._owner == me:
self._count = self._count + 1 self._count = self._count + 1
if __debug__: if __debug__:
self._note("%s.acquire(%s): recursive success", self, blocking) self._note("%s.acquire(%s): recursive success", self, blocking)
...@@ -118,7 +120,7 @@ class _RLock(_Verbose): ...@@ -118,7 +120,7 @@ class _RLock(_Verbose):
__enter__ = acquire __enter__ = acquire
def release(self): def release(self):
if self._owner is not current_thread(): if self._owner != _get_ident():
raise RuntimeError("cannot release un-acquired lock") raise RuntimeError("cannot release un-acquired lock")
self._count = count = self._count - 1 self._count = count = self._count - 1
if not count: if not count:
...@@ -152,7 +154,7 @@ class _RLock(_Verbose): ...@@ -152,7 +154,7 @@ class _RLock(_Verbose):
return (count, owner) return (count, owner)
def _is_owned(self): def _is_owned(self):
return self._owner is current_thread() return self._owner == _get_ident()
def Condition(*args, **kwargs): def Condition(*args, **kwargs):
......
...@@ -40,6 +40,10 @@ Core and Builtins ...@@ -40,6 +40,10 @@ Core and Builtins
Library 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 - Issue #7187: Importlib would not silence the IOError raised when trying to
write new bytecode when it was made read-only. write new bytecode when it was made read-only.
...@@ -140,6 +144,9 @@ Extension Modules ...@@ -140,6 +144,9 @@ Extension Modules
Tests 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 - Issue #7248 (part 2): Use a unique temporary directory for importlib source
tests instead of tempfile.tempdir. This prevents the tests from sharing state tests instead of tempfile.tempdir. This prevents the tests from sharing state
between concurrent executions on the same system. between concurrent executions on the same system.
......
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