home *** CD-ROM | disk | FTP | other *** search
/ Freelog 116 / FreelogNo116-JuilletSeptembre2013.iso / Bureautique / gImageReader / gimagereader_0.9-1_win32.exe / bin / threading.pyc (.txt) < prev    next >
Python Compiled Bytecode  |  2011-03-24  |  26KB  |  892 lines

  1. # Source Generated with Decompyle++
  2. # File: in.pyc (Python 2.7)
  3.  
  4. """Thread module emulating a subset of Java's threading model."""
  5. import sys as _sys
  6.  
  7. try:
  8.     import thread
  9. except ImportError:
  10.     del _sys.modules[__name__]
  11.     raise 
  12.  
  13. import warnings
  14. from time import time as _time, sleep as _sleep
  15. from traceback import format_exc as _format_exc
  16. from collections import deque
  17. __all__ = [
  18.     'activeCount',
  19.     'active_count',
  20.     'Condition',
  21.     'currentThread',
  22.     'current_thread',
  23.     'enumerate',
  24.     'Event',
  25.     'Lock',
  26.     'RLock',
  27.     'Semaphore',
  28.     'BoundedSemaphore',
  29.     'Thread',
  30.     'Timer',
  31.     'setprofile',
  32.     'settrace',
  33.     'local',
  34.     'stack_size']
  35. _start_new_thread = thread.start_new_thread
  36. _allocate_lock = thread.allocate_lock
  37. _get_ident = thread.get_ident
  38. ThreadError = thread.error
  39. del thread
  40. warnings.filterwarnings('ignore', category = DeprecationWarning, module = 'threading', message = 'sys.exc_clear')
  41. _VERBOSE = False
  42.  
  43. class _Verbose(object):
  44.     
  45.     def __init__(self, verbose = None):
  46.         if verbose is None:
  47.             verbose = _VERBOSE
  48.         self._Verbose__verbose = verbose
  49.  
  50.     
  51.     def _note(self, format, *args):
  52.         if self._Verbose__verbose:
  53.             format = format % args
  54.             format = '%s: %s\n' % (current_thread().name, format)
  55.             _sys.stderr.write(format)
  56.  
  57.  
  58. _profile_hook = None
  59. _trace_hook = None
  60.  
  61. def setprofile(func):
  62.     global _profile_hook
  63.     _profile_hook = func
  64.  
  65.  
  66. def settrace(func):
  67.     global _trace_hook
  68.     _trace_hook = func
  69.  
  70. Lock = _allocate_lock
  71.  
  72. def RLock(*args, **kwargs):
  73.     return _RLock(*args, **kwargs)
  74.  
  75.  
  76. class _RLock(_Verbose):
  77.     
  78.     def __init__(self, verbose = None):
  79.         _Verbose.__init__(self, verbose)
  80.         self._RLock__block = _allocate_lock()
  81.         self._RLock__owner = None
  82.         self._RLock__count = 0
  83.  
  84.     
  85.     def __repr__(self):
  86.         owner = self._RLock__owner
  87.         
  88.         try:
  89.             owner = _active[owner].name
  90.         except KeyError:
  91.             pass
  92.  
  93.         return '<%s owner=%r count=%d>' % (self.__class__.__name__, owner, self._RLock__count)
  94.  
  95.     
  96.     def acquire(self, blocking = 1):
  97.         me = _get_ident()
  98.         if self._RLock__owner == me:
  99.             self._RLock__count = self._RLock__count + 1
  100.             self._note('%s.acquire(%s): recursive success', self, blocking)
  101.             return 1
  102.         rc = None._RLock__block.acquire(blocking)
  103.         if rc:
  104.             self._RLock__owner = me
  105.             self._RLock__count = 1
  106.             self._note('%s.acquire(%s): initial success', self, blocking)
  107.         else:
  108.             self._note('%s.acquire(%s): failure', self, blocking)
  109.         return rc
  110.  
  111.     __enter__ = acquire
  112.     
  113.     def release(self):
  114.         if self._RLock__owner != _get_ident():
  115.             raise RuntimeError('cannot release un-acquired lock')
  116.         self._RLock__count = count = self._RLock__count - 1
  117.         if not count:
  118.             self._RLock__owner = None
  119.             self._RLock__block.release()
  120.             self._note('%s.release(): final release', self)
  121.         else:
  122.             self._note('%s.release(): non-final release', self)
  123.  
  124.     
  125.     def __exit__(self, t, v, tb):
  126.         self.release()
  127.  
  128.     
  129.     def _acquire_restore(self, count_owner):
  130.         (count, owner) = count_owner
  131.         self._RLock__block.acquire()
  132.         self._RLock__count = count
  133.         self._RLock__owner = owner
  134.         self._note('%s._acquire_restore()', self)
  135.  
  136.     
  137.     def _release_save(self):
  138.         self._note('%s._release_save()', self)
  139.         count = self._RLock__count
  140.         self._RLock__count = 0
  141.         owner = self._RLock__owner
  142.         self._RLock__owner = None
  143.         self._RLock__block.release()
  144.         return (count, owner)
  145.  
  146.     
  147.     def _is_owned(self):
  148.         return self._RLock__owner == _get_ident()
  149.  
  150.  
  151.  
  152. def Condition(*args, **kwargs):
  153.     return _Condition(*args, **kwargs)
  154.  
  155.  
  156. class _Condition(_Verbose):
  157.     
  158.     def __init__(self, lock = None, verbose = None):
  159.         _Verbose.__init__(self, verbose)
  160.         if lock is None:
  161.             lock = RLock()
  162.         self._Condition__lock = lock
  163.         self.acquire = lock.acquire
  164.         self.release = lock.release
  165.         
  166.         try:
  167.             self._release_save = lock._release_save
  168.         except AttributeError:
  169.             pass
  170.  
  171.         
  172.         try:
  173.             self._acquire_restore = lock._acquire_restore
  174.         except AttributeError:
  175.             pass
  176.  
  177.         
  178.         try:
  179.             self._is_owned = lock._is_owned
  180.         except AttributeError:
  181.             pass
  182.  
  183.         self._Condition__waiters = []
  184.  
  185.     
  186.     def __enter__(self):
  187.         return self._Condition__lock.__enter__()
  188.  
  189.     
  190.     def __exit__(self, *args):
  191.         return self._Condition__lock.__exit__(*args)
  192.  
  193.     
  194.     def __repr__(self):
  195.         return '<Condition(%s, %d)>' % (self._Condition__lock, len(self._Condition__waiters))
  196.  
  197.     
  198.     def _release_save(self):
  199.         self._Condition__lock.release()
  200.  
  201.     
  202.     def _acquire_restore(self, x):
  203.         self._Condition__lock.acquire()
  204.  
  205.     
  206.     def _is_owned(self):
  207.         if self._Condition__lock.acquire(0):
  208.             self._Condition__lock.release()
  209.             return False
  210.         return None
  211.  
  212.     
  213.     def wait(self, timeout = None):
  214.         if not self._is_owned():
  215.             raise RuntimeError('cannot wait on un-acquired lock')
  216.         waiter = _allocate_lock()
  217.         waiter.acquire()
  218.         self._Condition__waiters.append(waiter)
  219.         saved_state = self._release_save()
  220.         
  221.         try:
  222.             if timeout is None:
  223.                 waiter.acquire()
  224.                 self._note('%s.wait(): got it', self)
  225.             else:
  226.                 endtime = _time() + timeout
  227.                 delay = 0.0005
  228.                 while True:
  229.                     gotit = waiter.acquire(0)
  230.                     if gotit:
  231.                         break
  232.                     remaining = endtime - _time()
  233.                     if remaining <= 0:
  234.                         break
  235.                     delay = min(delay * 2, remaining, 0.05)
  236.                     _sleep(delay)
  237.                 if not gotit:
  238.                     self._note('%s.wait(%s): timed out', self, timeout)
  239.                     
  240.                     try:
  241.                         self._Condition__waiters.remove(waiter)
  242.                     except ValueError:
  243.                         pass
  244.                     
  245.  
  246.                 self._note('%s.wait(%s): got it', self, timeout)
  247.         finally:
  248.             self._acquire_restore(saved_state)
  249.  
  250.  
  251.     
  252.     def notify(self, n = 1):
  253.         if not self._is_owned():
  254.             raise RuntimeError('cannot notify on un-acquired lock')
  255.         _Condition__waiters = self._Condition__waiters
  256.         waiters = _Condition__waiters[:n]
  257.         None(None._note, '%s.notify(): notifying %d waiter%s', self, n if not waiters else '')
  258.         for waiter in waiters:
  259.             waiter.release()
  260.             
  261.             try:
  262.                 _Condition__waiters.remove(waiter)
  263.             continue
  264.             except ValueError:
  265.                 continue
  266.             
  267.  
  268.         
  269.  
  270.     
  271.     def notifyAll(self):
  272.         self.notify(len(self._Condition__waiters))
  273.  
  274.     notify_all = notifyAll
  275.  
  276.  
  277. def Semaphore(*args, **kwargs):
  278.     return _Semaphore(*args, **kwargs)
  279.  
  280.  
  281. class _Semaphore(_Verbose):
  282.     
  283.     def __init__(self, value = 1, verbose = None):
  284.         if value < 0:
  285.             raise ValueError('semaphore initial value must be >= 0')
  286.         _Verbose.__init__(self, verbose)
  287.         self._Semaphore__cond = Condition(Lock())
  288.         self._Semaphore__value = value
  289.  
  290.     
  291.     def acquire(self, blocking = 1):
  292.         rc = False
  293.         self._Semaphore__cond.acquire()
  294.         while self._Semaphore__value == 0:
  295.             if not blocking:
  296.                 break
  297.             self._note('%s.acquire(%s): blocked waiting, value=%s', self, blocking, self._Semaphore__value)
  298.             self._Semaphore__cond.wait()
  299.         self._Semaphore__value = self._Semaphore__value - 1
  300.         self._note('%s.acquire: success, value=%s', self, self._Semaphore__value)
  301.         rc = True
  302.         self._Semaphore__cond.release()
  303.         return rc
  304.  
  305.     __enter__ = acquire
  306.     
  307.     def release(self):
  308.         self._Semaphore__cond.acquire()
  309.         self._Semaphore__value = self._Semaphore__value + 1
  310.         self._note('%s.release: success, value=%s', self, self._Semaphore__value)
  311.         self._Semaphore__cond.notify()
  312.         self._Semaphore__cond.release()
  313.  
  314.     
  315.     def __exit__(self, t, v, tb):
  316.         self.release()
  317.  
  318.  
  319.  
  320. def BoundedSemaphore(*args, **kwargs):
  321.     return _BoundedSemaphore(*args, **kwargs)
  322.  
  323.  
  324. class _BoundedSemaphore(_Semaphore):
  325.     '''Semaphore that checks that # releases is <= # acquires'''
  326.     
  327.     def __init__(self, value = 1, verbose = None):
  328.         _Semaphore.__init__(self, value, verbose)
  329.         self._initial_value = value
  330.  
  331.     
  332.     def release(self):
  333.         if self._Semaphore__value >= self._initial_value:
  334.             raise ValueError, 'Semaphore released too many times'
  335.         return _Semaphore.release(self)
  336.  
  337.  
  338.  
  339. def Event(*args, **kwargs):
  340.     return _Event(*args, **kwargs)
  341.  
  342.  
  343. class _Event(_Verbose):
  344.     
  345.     def __init__(self, verbose = None):
  346.         _Verbose.__init__(self, verbose)
  347.         self._Event__cond = Condition(Lock())
  348.         self._Event__flag = False
  349.  
  350.     
  351.     def isSet(self):
  352.         return self._Event__flag
  353.  
  354.     is_set = isSet
  355.     
  356.     def set(self):
  357.         self._Event__cond.acquire()
  358.         
  359.         try:
  360.             self._Event__flag = True
  361.             self._Event__cond.notify_all()
  362.         finally:
  363.             self._Event__cond.release()
  364.  
  365.  
  366.     
  367.     def clear(self):
  368.         self._Event__cond.acquire()
  369.         
  370.         try:
  371.             self._Event__flag = False
  372.         finally:
  373.             self._Event__cond.release()
  374.  
  375.  
  376.     
  377.     def wait(self, timeout = None):
  378.         self._Event__cond.acquire()
  379.         
  380.         try:
  381.             if not self._Event__flag:
  382.                 self._Event__cond.wait(timeout)
  383.             return self._Event__flag
  384.         finally:
  385.             self._Event__cond.release()
  386.  
  387.  
  388.  
  389. _counter = 0
  390.  
  391. def _newname(template = 'Thread-%d'):
  392.     global _counter
  393.     _counter = _counter + 1
  394.     return template % _counter
  395.  
  396. _active_limbo_lock = _allocate_lock()
  397. _active = { }
  398. _limbo = { }
  399.  
  400. class Thread(_Verbose):
  401.     __initialized = False
  402.     __exc_info = _sys.exc_info
  403.     __exc_clear = _sys.exc_clear
  404.     
  405.     def __init__(self, group = None, target = None, name = None, args = (), kwargs = None, verbose = None):
  406.         if not group is None:
  407.             raise AssertionError, 'group argument must be None for now'
  408.         None.__init__(self, verbose)
  409.         if kwargs is None:
  410.             kwargs = { }
  411.         self._Thread__target = target
  412.         if not name:
  413.             pass
  414.         self._Thread__name = str(_newname())
  415.         self._Thread__args = args
  416.         self._Thread__kwargs = kwargs
  417.         self._Thread__daemonic = self._set_daemon()
  418.         self._Thread__ident = None
  419.         self._Thread__started = Event()
  420.         self._Thread__stopped = False
  421.         self._Thread__block = Condition(Lock())
  422.         self._Thread__initialized = True
  423.         self._Thread__stderr = _sys.stderr
  424.  
  425.     
  426.     def _set_daemon(self):
  427.         return current_thread().daemon
  428.  
  429.     
  430.     def __repr__(self):
  431.         if not self._Thread__initialized:
  432.             raise AssertionError, 'Thread.__init__() was not called'
  433.         status = None
  434.         if self._Thread__started.is_set():
  435.             status = 'started'
  436.         if self._Thread__stopped:
  437.             status = 'stopped'
  438.         if self._Thread__daemonic:
  439.             status += ' daemon'
  440.         if self._Thread__ident is not None:
  441.             status += ' %s' % self._Thread__ident
  442.         return '<%s(%s, %s)>' % (self.__class__.__name__, self._Thread__name, status)
  443.  
  444.     
  445.     def start(self):
  446.         if not self._Thread__initialized:
  447.             raise RuntimeError('thread.__init__() not called')
  448.         if self._Thread__started.is_set():
  449.             raise RuntimeError('threads can only be started once')
  450.         self._note('%s.start(): starting thread', self)
  451.         with _active_limbo_lock:
  452.             _limbo[self] = self
  453.         
  454.         try:
  455.             _start_new_thread(self._Thread__bootstrap, ())
  456.         except Exception:
  457.             with _active_limbo_lock:
  458.                 del _limbo[self]
  459.         else:
  460.             raise 
  461.  
  462.         self._Thread__started.wait()
  463.  
  464.     
  465.     def run(self):
  466.         
  467.         try:
  468.             if self._Thread__target:
  469.                 self._Thread__target(*self._Thread__args, **self._Thread__kwargs)
  470.         finally:
  471.             del self._Thread__target
  472.             del self._Thread__args
  473.             del self._Thread__kwargs
  474.  
  475.  
  476.     
  477.     def __bootstrap(self):
  478.         
  479.         try:
  480.             self._Thread__bootstrap_inner()
  481.         except:
  482.             if self._Thread__daemonic and _sys is None:
  483.                 return None
  484.  
  485.  
  486.     
  487.     def _set_ident(self):
  488.         self._Thread__ident = _get_ident()
  489.  
  490.     
  491.     def __bootstrap_inner(self):
  492.         
  493.         try:
  494.             self._set_ident()
  495.             self._Thread__started.set()
  496.             with _active_limbo_lock:
  497.                 _active[self._Thread__ident] = self
  498.                 del _limbo[self]
  499.             self._note('%s.__bootstrap(): thread started', self)
  500.             if _trace_hook:
  501.                 self._note('%s.__bootstrap(): registering trace hook', self)
  502.                 _sys.settrace(_trace_hook)
  503.             if _profile_hook:
  504.                 self._note('%s.__bootstrap(): registering profile hook', self)
  505.                 _sys.setprofile(_profile_hook)
  506.             
  507.             try:
  508.                 self.run()
  509.             except SystemExit:
  510.                 self._note('%s.__bootstrap(): raised SystemExit', self)
  511.             except:
  512.                 self._note('%s.__bootstrap(): unhandled exception', self)
  513.                 if _sys:
  514.                     _sys.stderr.write('Exception in thread %s:\n%s\n' % (self.name, _format_exc()))
  515.                 else:
  516.                     (exc_type, exc_value, exc_tb) = self._Thread__exc_info()
  517.                     
  518.                     try:
  519.                         print >>self._Thread__stderr, 'Exception in thread ' + self.name + ' (most likely raised during interpreter shutdown):'
  520.                         print >>self._Thread__stderr, 'Traceback (most recent call last):'
  521.                         while exc_tb:
  522.                             print >>self._Thread__stderr, '  File "%s", line %s, in %s' % (exc_tb.tb_frame.f_code.co_filename, exc_tb.tb_lineno, exc_tb.tb_frame.f_code.co_name)
  523.                             exc_tb = exc_tb.tb_next
  524.                         print >>self._Thread__stderr, '%s: %s' % (exc_type, exc_value)
  525.                     finally:
  526.                         del exc_type
  527.                         del exc_value
  528.                         del exc_tb
  529.  
  530.             else:
  531.                 self._note('%s.__bootstrap(): normal return', self)
  532.             finally:
  533.                 self._Thread__exc_clear()
  534.  
  535.         finally:
  536.             with _active_limbo_lock:
  537.                 self._Thread__stop()
  538.                 
  539.                 try:
  540.                     del _active[_get_ident()]
  541.                 except:
  542.                     pass
  543.  
  544.  
  545.  
  546.     
  547.     def __stop(self):
  548.         self._Thread__block.acquire()
  549.         self._Thread__stopped = True
  550.         self._Thread__block.notify_all()
  551.         self._Thread__block.release()
  552.  
  553.     
  554.     def __delete(self):
  555.         '''Remove current thread from the dict of currently running threads.'''
  556.         
  557.         try:
  558.             with _active_limbo_lock:
  559.                 del _active[_get_ident()]
  560.         except KeyError:
  561.             if 'dummy_threading' not in _sys.modules:
  562.                 raise 
  563.  
  564.  
  565.     
  566.     def join(self, timeout = None):
  567.         if not self._Thread__initialized:
  568.             raise RuntimeError('Thread.__init__() not called')
  569.         if not self._Thread__started.is_set():
  570.             raise RuntimeError('cannot join thread before it is started')
  571.         if self is current_thread():
  572.             raise RuntimeError('cannot join current thread')
  573.         if not self._Thread__stopped:
  574.             self._note('%s.join(): waiting until thread stops', self)
  575.         self._Thread__block.acquire()
  576.         
  577.         try:
  578.             if timeout is None:
  579.                 while not self._Thread__stopped:
  580.                     self._Thread__block.wait()
  581.                 self._note('%s.join(): thread stopped', self)
  582.             else:
  583.                 deadline = _time() + timeout
  584.                 while not self._Thread__stopped:
  585.                     delay = deadline - _time()
  586.                     if delay <= 0:
  587.                         self._note('%s.join(): timed out', self)
  588.                         break
  589.                     self._Thread__block.wait(delay)
  590.                 self._note('%s.join(): thread stopped', self)
  591.         finally:
  592.             self._Thread__block.release()
  593.  
  594.  
  595.     
  596.     def name(self):
  597.         if not self._Thread__initialized:
  598.             raise AssertionError, 'Thread.__init__() not called'
  599.         return None._Thread__name
  600.  
  601.     name = property(name)
  602.     
  603.     def name(self, name):
  604.         if not self._Thread__initialized:
  605.             raise AssertionError, 'Thread.__init__() not called'
  606.         self._Thread__name = None(name)
  607.  
  608.     name = name.setter(name)
  609.     
  610.     def ident(self):
  611.         if not self._Thread__initialized:
  612.             raise AssertionError, 'Thread.__init__() not called'
  613.         return None._Thread__ident
  614.  
  615.     ident = property(ident)
  616.     
  617.     def isAlive(self):
  618.         return None if not self._Thread__initialized else not (self._Thread__stopped)
  619.  
  620.     is_alive = isAlive
  621.     
  622.     def daemon(self):
  623.         if not self._Thread__initialized:
  624.             raise AssertionError, 'Thread.__init__() not called'
  625.         return None._Thread__daemonic
  626.  
  627.     daemon = property(daemon)
  628.     
  629.     def daemon(self, daemonic):
  630.         if not self._Thread__initialized:
  631.             raise RuntimeError('Thread.__init__() not called')
  632.         if self._Thread__started.is_set():
  633.             raise RuntimeError('cannot set daemon status of active thread')
  634.         self._Thread__daemonic = daemonic
  635.  
  636.     daemon = daemon.setter(daemon)
  637.     
  638.     def isDaemon(self):
  639.         return self.daemon
  640.  
  641.     
  642.     def setDaemon(self, daemonic):
  643.         self.daemon = daemonic
  644.  
  645.     
  646.     def getName(self):
  647.         return self.name
  648.  
  649.     
  650.     def setName(self, name):
  651.         self.name = name
  652.  
  653.  
  654.  
  655. def Timer(*args, **kwargs):
  656.     return _Timer(*args, **kwargs)
  657.  
  658.  
  659. class _Timer(Thread):
  660.     """Call a function after a specified number of seconds:
  661.  
  662.     t = Timer(30.0, f, args=[], kwargs={})
  663.     t.start()
  664.     t.cancel() # stop the timer's action if it's still waiting
  665.     """
  666.     
  667.     def __init__(self, interval, function, args = [], kwargs = { }):
  668.         Thread.__init__(self)
  669.         self.interval = interval
  670.         self.function = function
  671.         self.args = args
  672.         self.kwargs = kwargs
  673.         self.finished = Event()
  674.  
  675.     
  676.     def cancel(self):
  677.         """Stop the timer if it hasn't finished yet"""
  678.         self.finished.set()
  679.  
  680.     
  681.     def run(self):
  682.         self.finished.wait(self.interval)
  683.         if not self.finished.is_set():
  684.             self.function(*self.args, **self.kwargs)
  685.         self.finished.set()
  686.  
  687.  
  688.  
  689. class _MainThread(Thread):
  690.     
  691.     def __init__(self):
  692.         Thread.__init__(self, name = 'MainThread')
  693.         self._Thread__started.set()
  694.         self._set_ident()
  695.         with _active_limbo_lock:
  696.             _active[_get_ident()] = self
  697.  
  698.     
  699.     def _set_daemon(self):
  700.         return False
  701.  
  702.     
  703.     def _exitfunc(self):
  704.         self._Thread__stop()
  705.         t = _pickSomeNonDaemonThread()
  706.         if t:
  707.             self._note('%s: waiting for other threads', self)
  708.         while t:
  709.             t.join()
  710.             t = _pickSomeNonDaemonThread()
  711.         self._note('%s: exiting', self)
  712.         self._Thread__delete()
  713.  
  714.  
  715.  
  716. def _pickSomeNonDaemonThread():
  717.     for t in enumerate():
  718.         if not (t.daemon) and t.is_alive():
  719.             return t
  720.     
  721.  
  722.  
  723. class _DummyThread(Thread):
  724.     
  725.     def __init__(self):
  726.         Thread.__init__(self, name = _newname('Dummy-%d'))
  727.         del self._Thread__block
  728.         self._Thread__started.set()
  729.         self._set_ident()
  730.         with _active_limbo_lock:
  731.             _active[_get_ident()] = self
  732.  
  733.     
  734.     def _set_daemon(self):
  735.         return True
  736.  
  737.     
  738.     def join(self, timeout = None):
  739.         if not False:
  740.             raise AssertionError, 'cannot join a dummy thread'
  741.  
  742.  
  743.  
  744. def currentThread():
  745.     
  746.     try:
  747.         return _active[_get_ident()]
  748.     except KeyError:
  749.         return _DummyThread()
  750.  
  751.  
  752. current_thread = currentThread
  753.  
  754. def activeCount():
  755.     with _active_limbo_lock:
  756.         return len(_active) + len(_limbo)
  757.  
  758. active_count = activeCount
  759.  
  760. def _enumerate():
  761.     return _active.values() + _limbo.values()
  762.  
  763.  
  764. def enumerate():
  765.     with _active_limbo_lock:
  766.         return _active.values() + _limbo.values()
  767.  
  768. from thread import stack_size
  769. _shutdown = _MainThread()._exitfunc
  770.  
  771. try:
  772.     from thread import _local as local
  773. except ImportError:
  774.     from _threading_local import local
  775.  
  776.  
  777. def _after_fork():
  778.     global _active_limbo_lock
  779.     _active_limbo_lock = _allocate_lock()
  780.     new_active = { }
  781.     current = current_thread()
  782.     with _active_limbo_lock:
  783.         for thread in _active.itervalues():
  784.             if thread is current:
  785.                 ident = _get_ident()
  786.                 thread._Thread__ident = ident
  787.                 new_active[ident] = thread
  788.                 continue
  789.             thread._Thread__stopped = True
  790.         
  791.         _limbo.clear()
  792.         _active.clear()
  793.         _active.update(new_active)
  794.         if not len(_active) == 1:
  795.             raise AssertionError
  796.  
  797.  
  798. def _test():
  799.     
  800.     class BoundedQueue(_Verbose):
  801.         
  802.         def __init__(self, limit):
  803.             _Verbose.__init__(self)
  804.             self.mon = RLock()
  805.             self.rc = Condition(self.mon)
  806.             self.wc = Condition(self.mon)
  807.             self.limit = limit
  808.             self.queue = deque()
  809.  
  810.         
  811.         def put(self, item):
  812.             self.mon.acquire()
  813.             while len(self.queue) >= self.limit:
  814.                 self._note('put(%s): queue full', item)
  815.                 self.wc.wait()
  816.             self.queue.append(item)
  817.             self._note('put(%s): appended, length now %d', item, len(self.queue))
  818.             self.rc.notify()
  819.             self.mon.release()
  820.  
  821.         
  822.         def get(self):
  823.             self.mon.acquire()
  824.             while not self.queue:
  825.                 self._note('get(): queue empty')
  826.                 self.rc.wait()
  827.             item = self.queue.popleft()
  828.             self._note('get(): got %s, %d left', item, len(self.queue))
  829.             self.wc.notify()
  830.             self.mon.release()
  831.             return item
  832.  
  833.  
  834.     
  835.     class ProducerThread(Thread):
  836.         
  837.         def __init__(self, queue, quota):
  838.             Thread.__init__(self, name = 'Producer')
  839.             self.queue = queue
  840.             self.quota = quota
  841.  
  842.         
  843.         def run(self):
  844.             random = random
  845.             import random
  846.             counter = 0
  847.             while counter < self.quota:
  848.                 counter = counter + 1
  849.                 self.queue.put('%s.%d' % (self.name, counter))
  850.                 _sleep(random() * 1e-05)
  851.  
  852.  
  853.     
  854.     class ConsumerThread(Thread):
  855.         
  856.         def __init__(self, queue, count):
  857.             Thread.__init__(self, name = 'Consumer')
  858.             self.queue = queue
  859.             self.count = count
  860.  
  861.         
  862.         def run(self):
  863.             while self.count > 0:
  864.                 item = self.queue.get()
  865.                 print item
  866.                 self.count = self.count - 1
  867.  
  868.  
  869.     NP = 3
  870.     QL = 4
  871.     NI = 5
  872.     Q = BoundedQueue(QL)
  873.     P = []
  874.     for i in range(NP):
  875.         t = ProducerThread(Q, NI)
  876.         t.name = 'Producer-%d' % (i + 1)
  877.         P.append(t)
  878.     
  879.     C = ConsumerThread(Q, NI * NP)
  880.     for t in P:
  881.         t.start()
  882.         _sleep(1e-06)
  883.     
  884.     C.start()
  885.     for t in P:
  886.         t.join()
  887.     
  888.     C.join()
  889.  
  890. if __name__ == '__main__':
  891.     _test()
  892.