/ src / network / threads.py
threads.py
 1  """Threading primitives for the network package"""
 2  
 3  import logging
 4  import random
 5  import threading
 6  from contextlib import contextmanager
 7  
 8  
 9  class StoppableThread(threading.Thread):
10      """Base class for application threads with stopThread method"""
11      name = None
12      logger = logging.getLogger('default')
13  
14      def __init__(self, name=None):
15          if name:
16              self.name = name
17          super(StoppableThread, self).__init__(name=self.name)
18          self.stop = threading.Event()
19          self._stopped = False
20          random.seed()
21          self.logger.info('Init thread %s', self.name)
22  
23      def stopThread(self):
24          """Stop the thread"""
25          self._stopped = True
26          self.stop.set()
27  
28  
29  class BusyError(threading.ThreadError):
30      """
31      Thread error raised when another connection holds the lock
32      we are trying to acquire.
33      """
34      pass
35  
36  
37  @contextmanager
38  def nonBlocking(lock):
39      """
40      A context manager which acquires given lock non-blocking
41      and raises BusyError if failed to acquire.
42      """
43      locked = lock.acquire(False)
44      if not locked:
45          raise BusyError
46      try:
47          yield
48      finally:
49          lock.release()