summaryrefslogtreecommitdiffstats
path: root/Lib/threading.py
diff options
context:
space:
mode:
Diffstat (limited to 'Lib/threading.py')
-rw-r--r--Lib/threading.py58
1 files changed, 45 insertions, 13 deletions
diff --git a/Lib/threading.py b/Lib/threading.py
index fecd3cc..7b07265 100644
--- a/Lib/threading.py
+++ b/Lib/threading.py
@@ -85,9 +85,10 @@ class _RLock(_Verbose):
self.__count = 0
def __repr__(self):
+ owner = self.__owner
return "<%s(%s, %d)>" % (
self.__class__.__name__,
- self.__owner and self.__owner.getName(),
+ owner and owner.getName(),
self.__count)
def acquire(self, blocking=1):
@@ -111,8 +112,8 @@ class _RLock(_Verbose):
__enter__ = acquire
def release(self):
- me = currentThread()
- assert self.__owner is me, "release() of un-acquire()d lock"
+ if self.__owner is not currentThread():
+ raise RuntimeError("cannot release un-aquired lock")
self.__count = count = self.__count - 1
if not count:
self.__owner = None
@@ -204,7 +205,8 @@ class _Condition(_Verbose):
return True
def wait(self, timeout=None):
- assert self._is_owned(), "wait() of un-acquire()d lock"
+ if not self._is_owned():
+ raise RuntimeError("cannot wait on un-aquired lock")
waiter = _allocate_lock()
waiter.acquire()
self.__waiters.append(waiter)
@@ -245,7 +247,8 @@ class _Condition(_Verbose):
self._acquire_restore(saved_state)
def notify(self, n=1):
- assert self._is_owned(), "notify() of un-acquire()d lock"
+ if not self._is_owned():
+ raise RuntimeError("cannot notify on un-aquired lock")
__waiters = self.__waiters
waiters = __waiters[:n]
if not waiters:
@@ -273,7 +276,8 @@ class _Semaphore(_Verbose):
# After Tim Peters' semaphore class, but not quite the same (no maximum)
def __init__(self, value=1, verbose=None):
- assert value >= 0, "Semaphore initial value must be >= 0"
+ if value < 0:
+ raise ValueError("semaphore initial value must be >= 0")
_Verbose.__init__(self, verbose)
self.__cond = Condition(Lock())
self.__value = value
@@ -424,8 +428,10 @@ class Thread(_Verbose):
return "<%s(%s, %s)>" % (self.__class__.__name__, self.__name, status)
def start(self):
- assert self.__initialized, "Thread.__init__() not called"
- assert not self.__started, "thread already started"
+ if not self.__initialized:
+ raise RuntimeError("thread.__init__() not called")
+ if self.__started:
+ raise RuntimeError("thread already started")
if __debug__:
self._note("%s.start(): starting thread", self)
_active_limbo_lock.acquire()
@@ -440,6 +446,26 @@ class Thread(_Verbose):
self.__target(*self.__args, **self.__kwargs)
def __bootstrap(self):
+ # Wrapper around the real bootstrap code that ignores
+ # exceptions during interpreter cleanup. Those typically
+ # happen when a daemon thread wakes up at an unfortunate
+ # moment, finds the world around it destroyed, and raises some
+ # random exception *** while trying to report the exception in
+ # __bootstrap_inner() below ***. Those random exceptions
+ # don't help anybody, and they confuse users, so we suppress
+ # them. We suppress them only when it appears that the world
+ # indeed has already been destroyed, so that exceptions in
+ # __bootstrap_inner() during normal business hours are properly
+ # reported. Also, we only suppress them for daemonic threads;
+ # if a non-daemonic encounters this, something else is wrong.
+ try:
+ self.__bootstrap_inner()
+ except:
+ if self.__daemonic and _sys is None:
+ return
+ raise
+
+ def __bootstrap_inner(self):
try:
self.__started = True
_active_limbo_lock.acquire()
@@ -545,9 +571,13 @@ class Thread(_Verbose):
_active_limbo_lock.release()
def join(self, timeout=None):
- assert self.__initialized, "Thread.__init__() not called"
- assert self.__started, "cannot join thread before it is started"
- assert self is not currentThread(), "cannot join current thread"
+ if not self.__initialized:
+ raise RuntimeError("Thread.__init__() not called")
+ if not self.__started:
+ raise RuntimeError("cannot join thread before it is started")
+ if self is currentThread():
+ raise RuntimeError("cannot join current thread")
+
if __debug__:
if not self.__stopped:
self._note("%s.join(): waiting until thread stops", self)
@@ -590,8 +620,10 @@ class Thread(_Verbose):
return self.__daemonic
def setDaemon(self, daemonic):
- assert self.__initialized, "Thread.__init__() not called"
- assert not self.__started, "cannot set daemon status of active thread"
+ if not self.__initialized:
+ raise RuntimeError("Thread.__init__() not called")
+ if self.__started:
+ raise RuntimeError("cannot set daemon status of active thread");
self.__daemonic = daemonic
# The timer class was contributed by Itamar Shtull-Trauring