home *** CD-ROM | disk | FTP | other *** search
/ Maximum CD 2012 January / maximum-cd-2012-01.iso / DiscContents / digsby_setup.exe / lib / util / threads / timeout_thread.pyo (.txt) < prev   
Encoding:
Python Compiled Bytecode  |  2011-10-05  |  16.0 KB  |  558 lines

  1. # Source Generated with Decompyle++
  2. # File: in.pyo (Python 2.6)
  3.  
  4. from __future__ import with_statement
  5. from itertools import count
  6. from operator import attrgetter
  7. from threading import Condition
  8. from peak.util.imports import whenImported
  9. import sys
  10. from util import default_timer
  11. from logging import getLogger
  12. log = getLogger('timeout_thread')
  13. from traceback import print_exc
  14. from os.path import split as pathsplit
  15. from functools import wraps
  16. TR = None
  17. CV = Condition()
  18. from heapq import heappush, heapify, heappop
  19. from bgthread import BackgroundThread
  20. __all__ = [
  21.     'TimeOut',
  22.     'Timer',
  23.     'call_later',
  24.     'ResetTimer',
  25.     'RepeatTimer',
  26.     'delayed_call']
  27.  
  28. class TimeRouter(BackgroundThread):
  29.     ids = count()
  30.     
  31.     def __init__(self, cv):
  32.         BackgroundThread.__init__(self, name = 'TimeRouter')
  33.         self.count = self.ids.next()
  34.         self.done = False
  35.         self.cv = cv
  36.         self.timeouts = []
  37.  
  38.     
  39.     def add(self, timeout):
  40.         self.cv.__enter__()
  41.         
  42.         try:
  43.             timeout.compute_timeout()
  44.             self.cv.notifyAll()
  45.         finally:
  46.             pass
  47.  
  48.  
  49.     
  50.     def stop(self):
  51.         self.cv.__enter__()
  52.         
  53.         try:
  54.             self.done = True
  55.             del TR.timeouts[:]
  56.             TimeRouter.add = Null
  57.             TimeOut.start = Null
  58.             self.cv.notifyAll()
  59.         finally:
  60.             pass
  61.  
  62.  
  63.     join = stop
  64.     
  65.     def resort(self):
  66.         self.cv.__enter__()
  67.         
  68.         try:
  69.             heapify(self.timeouts)
  70.             self.cv.notifyAll()
  71.         finally:
  72.             pass
  73.  
  74.  
  75.     
  76.     def run(self):
  77.         use_profiler = use_profiler
  78.         import util.introspect
  79.         self.BeforeRun()
  80.         
  81.         try:
  82.             res = use_profiler(self, self._run)
  83.         finally:
  84.             self.AfterRun()
  85.  
  86.         return res
  87.  
  88.     
  89.     def _run(self):
  90.         global TR
  91.         self.cv.__enter__()
  92.         
  93.         try:
  94.             while not self.done:
  95.                 setattr(self, 'loopcount', getattr(self, 'loopcount', 0) + 1)
  96.                 timeouts = self.timeouts
  97.                 if len(timeouts) > 1000:
  98.                     log.warning('um thats a lot of timeouts: %d', len(timeouts))
  99.                 
  100.                 for x in timeouts:
  101.                     x.compute_timeout()
  102.                 
  103.                 heapify(timeouts)
  104.                 while timeouts and timeouts[0].finished():
  105.                     setattr(self, 'loopcount', getattr(self, 'loopcount', 0) + 1)
  106.                     heappop(timeouts)
  107.                 if not timeouts:
  108.                     t = None
  109.                     break
  110.                 
  111.                 t = timeouts[0].compute_timeout()
  112.                 while t <= 0:
  113.                     setattr(self, 'loopcount', getattr(self, 'loopcount', 0) + 1)
  114.                     front = heappop(timeouts)
  115.                     if not front.finished():
  116.                         self.cv.release()
  117.                         
  118.                         try:
  119.                             front.process()
  120.                         except Exception:
  121.                             e = None
  122.                             
  123.                             front.finished = lambda *a, **k: True
  124.                             print_exc()
  125.                             log.log(100, 'caught exception in process, FIX this NOW!: %r, %r', front, e)
  126.                             del e
  127.                         finally:
  128.                             self.cv.acquire()
  129.  
  130.                         if self.done:
  131.                             break
  132.                         
  133.                     
  134.                     if not front.finished():
  135.                         front.compute_timeout()
  136.                         heappush(timeouts, front)
  137.                     
  138.                     if not timeouts:
  139.                         t = None
  140.                         break
  141.                     
  142.                     t = timeouts[0].compute_timeout()
  143.                 if self.done:
  144.                     break
  145.                 
  146.                 if t is None:
  147.                     break
  148.                 
  149.                 self.cv.wait(t + t / 100)
  150.                 if self.done:
  151.                     break
  152.                 
  153.                 sys.exc_clear()
  154.             log.info('TimeRouter %r id(0x%x) is done', TR, id(TR))
  155.             TR = None
  156.         finally:
  157.             pass
  158.  
  159.  
  160.  
  161.  
  162. def join():
  163.     CV.__enter__()
  164.     
  165.     try:
  166.         if TR is not None:
  167.             TR.join()
  168.     finally:
  169.         pass
  170.  
  171.  
  172.  
  173. class TimeOut(object):
  174.     
  175.     def __init__(self):
  176.         self._cv = CV
  177.         self._started = False
  178.         self._finished = False
  179.  
  180.     
  181.     def __hash__(self):
  182.         return hash(id(self))
  183.  
  184.     
  185.     def start(self):
  186.         global TR
  187.         self._cv.__enter__()
  188.         
  189.         try:
  190.             self._started = True
  191.             self._finished = False
  192.             TR.add(self)
  193.             self._cv.notifyAll()
  194.         finally:
  195.             pass
  196.  
  197.  
  198.     
  199.     def stop(self):
  200.         self._cv.__enter__()
  201.         
  202.         try:
  203.             self._finished = True
  204.             self._cv.notifyAll()
  205.         finally:
  206.             pass
  207.  
  208.  
  209.     
  210.     def compute_timeout(self):
  211.         raise NotImplementedError
  212.  
  213.     last_computed = property(attrgetter('_last_computed'))
  214.     
  215.     def started(self):
  216.         return self._started
  217.  
  218.     
  219.     def finished(self):
  220.         return self._finished
  221.  
  222.     
  223.     def process(self):
  224.         raise NotImplementedError
  225.  
  226.     
  227.     def __cmp__(self, other):
  228.         ret = self.last_computed - other.last_computed
  229.         if ret > 0:
  230.             ret = 1
  231.         elif ret < 0:
  232.             ret = -1
  233.         else:
  234.             ret = cmp(hash(self), hash(other))
  235.         return ret
  236.  
  237.  
  238.  
  239. class Timer(TimeOut):
  240.     
  241.     def __init__(self, interval, function, *args, **kwargs):
  242.         int(interval)
  243.         self._interval = interval
  244.         self._func = function
  245.         self._args = args
  246.         self._kwargs = kwargs
  247.         self._called_from = self._getcaller()
  248.         TimeOut.__init__(self)
  249.  
  250.     
  251.     def _getcaller(self):
  252.         f = sys._getframe(2)
  253.         caller_name = f.f_code.co_name
  254.         filename = pathsplit(f.f_code.co_filename)[-1]
  255.         linenumber = f.f_code.co_firstlineno
  256.         self.called_from = '%s:%s:%s' % (filename, caller_name, linenumber)
  257.  
  258.     
  259.     def __repr__(self):
  260.         funcinfo = funcinfo
  261.         import util
  262.         return '<%s (from %s), callable is %s>' % (self.__class__.__name__, self.called_from, funcinfo(self._func))
  263.  
  264.     
  265.     def start(self):
  266.         self.done_at = default_timer() + self._interval
  267.         TimeOut.start(self)
  268.  
  269.     
  270.     def compute_timeout(self):
  271.         self._last_computed = self.done_at - default_timer()
  272.         return self._last_computed
  273.  
  274.     
  275.     def cancel(self):
  276.         self.stop()
  277.  
  278.     
  279.     def process(self):
  280.         self.stop()
  281.         self._func(*self._args, **self._kwargs)
  282.  
  283.     
  284.     def isAlive(self):
  285.         if self.started():
  286.             pass
  287.         return not self.finished()
  288.  
  289.     
  290.     def stop(self):
  291.         self._cv.__enter__()
  292.         
  293.         try:
  294.             self.done_at = default_timer()
  295.             self.compute_timeout()
  296.             TimeOut.stop(self)
  297.         finally:
  298.             pass
  299.  
  300.  
  301.     
  302.     def remaining(self):
  303.         return self.done_at - default_timer()
  304.  
  305.     remaining = property(remaining)
  306.  
  307.  
  308. def call_later(interval, function, *a, **k):
  309.     t = Timer(interval, function, *a, **k)
  310.     t.start()
  311.     return t
  312.  
  313.  
  314. class ResetTimer(Timer):
  315.     
  316.     def __init__(self, *a, **k):
  317.         Timer.__init__(self, *a, **k)
  318.         self.waiting = False
  319.  
  320.     
  321.     def compute_timeout(self):
  322.         if self.waiting:
  323.             self._last_computed = default_timer() + 5
  324.             return self._last_computed
  325.         return Timer.compute_timeout(self)
  326.  
  327.     
  328.     def process(self):
  329.         self._func(*self._args, **self._kwargs)
  330.         self.waiting = True
  331.  
  332.     
  333.     def temp_override(self, new_time):
  334.         self._cv.__enter__()
  335.         
  336.         try:
  337.             self.done_at = default_timer() + new_time
  338.             self._cv.notifyAll()
  339.         finally:
  340.             pass
  341.  
  342.  
  343.     
  344.     def reset(self, new_time = None):
  345.         self._cv.__enter__()
  346.         
  347.         try:
  348.             self.waiting = False
  349.             self.done_at = default_timer() + self._interval
  350.             if self.finished():
  351.                 self.start()
  352.             else:
  353.                 self._cv.notifyAll()
  354.         finally:
  355.             pass
  356.  
  357.  
  358.  
  359.  
  360. class RepeatTimer(Timer):
  361.     
  362.     def __init__(self, *a, **k):
  363.         Timer.__init__(self, *a, **k)
  364.         self.paused = None
  365.  
  366.     
  367.     def compute_timeout(self):
  368.         if self.paused is not None:
  369.             self._last_computed = self.paused
  370.             return self._last_computed
  371.         self._last_computed = self.done_at - default_timer()
  372.         return self._last_computed
  373.  
  374.     
  375.     def pause(self):
  376.         self._cv.__enter__()
  377.         
  378.         try:
  379.             if not self.compute_timeout():
  380.                 pass
  381.             self.paused = 0.01
  382.         finally:
  383.             pass
  384.  
  385.  
  386.     
  387.     def unpause(self):
  388.         self._cv.__enter__()
  389.         
  390.         try:
  391.             self.done_at = self.paused + default_timer()
  392.             self.paused = None
  393.         finally:
  394.             pass
  395.  
  396.  
  397.     
  398.     def temp_override(self, new_time):
  399.         self._cv.__enter__()
  400.         
  401.         try:
  402.             self.done_at = default_timer() + new_time
  403.             self._cv.notifyAll()
  404.         finally:
  405.             pass
  406.  
  407.  
  408.     
  409.     def temp_reset(self, new_time):
  410.         self._cv.__enter__()
  411.         
  412.         try:
  413.             self.paused = None
  414.             self.done_at = default_timer() + new_time
  415.             if not self.isAlive():
  416.                 TimeOut.start(self)
  417.             else:
  418.                 self._cv.notifyAll()
  419.         finally:
  420.             pass
  421.  
  422.  
  423.     
  424.     def process(self):
  425.         self._func(*self._args, **self._kwargs)
  426.         self.done_at = default_timer() + self._interval
  427.  
  428.     
  429.     def reset(self, new_time = None):
  430.         self._cv.__enter__()
  431.         
  432.         try:
  433.             self.paused = None
  434.             self.done_at = default_timer() + self._interval
  435.             if self.finished():
  436.                 self.start()
  437.             else:
  438.                 self._cv.notifyAll()
  439.         finally:
  440.             pass
  441.  
  442.  
  443.     
  444.     def stop(self):
  445.         self._cv.__enter__()
  446.         
  447.         try:
  448.             self.paused = None
  449.             Timer.stop(self)
  450.         finally:
  451.             pass
  452.  
  453.  
  454.  
  455.  
  456. def delayed_call(func, seconds, wxonly = False):
  457.     
  458.     def ontimer(*a, **k):
  459.         func._rtimer.stop()
  460.         func(*a, **k)
  461.  
  462.     
  463.     def wrapper(*a, **k):
  464.         
  465.         try:
  466.             timer = func._rtimer
  467.         except AttributeError:
  468.             if wxonly:
  469.                 import wx
  470.                 timer = func._rtimer = (None, None, wx.PyTimer)((lambda : ontimer(*a, **k)))
  471.                 timer.start = timer.reset = (lambda s = seconds * 1000, timer = timer: timer.Start(s))
  472.                 timer.stop = timer.Stop
  473.             else:
  474.                 timer = func._rtimer = None((None, ResetTimer, seconds), (lambda : ontimer(*a, **k)))
  475.             timer.start()
  476.  
  477.         timer.reset()
  478.         if wxonly:
  479.             
  480.             timer.notify = lambda : ontimer(*a, **k)
  481.         
  482.  
  483.     wrapper = (None, None, (None,), wraps(func))(wrapper)
  484.     return wrapper
  485.  
  486.  
  487. def TimeRouterCallLater(*a, **k):
  488.     t = Timer(0, *a, **k)
  489.     t._verbose = False
  490.     t.start()
  491.  
  492.  
  493. def wakeup():
  494.     TimeRouterCallLater((lambda : pass))
  495.  
  496.  
  497. def _register_call_later(callbacks):
  498.     callbacks.register_call_later('TimeRouter', TimeRouterCallLater)
  499.  
  500. whenImported('util.callbacks', _register_call_later)
  501. if __name__ == '__main__':
  502.     from util import CallCounter
  503.     
  504.     class WaitNSeconds(TimeOut):
  505.         
  506.         def __init__(self, seconds, name):
  507.             TimeOut.__init__(self)
  508.             self._finished = False
  509.             self.seconds = seconds
  510.             self.name = name
  511.             self.totaltime = 0
  512.             self.cc = CallCounter(4, self.stop)
  513.             self.done_at = default_timer() + seconds
  514.  
  515.         
  516.         def compute_timeout(self):
  517.             self._last_computed = self.done_at - default_timer()
  518.             return self._last_computed
  519.  
  520.         
  521.         def process(self):
  522.             x = (default_timer() - self.done_at) + self.seconds
  523.             self.totaltime += x
  524.             print '%s done, waited %f, total:%f' % (self.name, x, self.totaltime)
  525.             self.done_at = default_timer() + self.seconds
  526.             self.cc()
  527.  
  528.  
  529.     one = WaitNSeconds(1, 'one')
  530.     two = WaitNSeconds(3, 'two')
  531.     three = WaitNSeconds(3, 'three')
  532.     two.done_at = three.done_at
  533.     one.start()
  534.     two.start()
  535.     three.start()
  536.     TR.join()
  537.     
  538.     def cb():
  539.         print 'the time is now:', default_timer()
  540.  
  541.     _5sec = ResetTimer(5, cb)
  542.     _2sec = ResetTimer(2, cb)
  543.     _5sec.start()
  544.     _2sec.start()
  545.     from time import sleep
  546.     for i in range(5):
  547.         sleep(2)
  548.         _2sec.reset()
  549.         print 'reset 2'
  550.     
  551.     _5sec.reset()
  552.     print 'reset 5'
  553.     sleep(6)
  554.     _5sec.stop()
  555.     _2sec.stop()
  556.     TR.join()
  557.  
  558.