home *** CD-ROM | disk | FTP | other *** search
/ Maximum CD 2009 June / maximum-cd-2009-06.iso / DiscContents / digsby_setup.exe / lib / util / threads / timeout_thread.pyo (.txt) < prev   
Encoding:
Python Compiled Bytecode  |  2009-02-26  |  15.9 KB  |  574 lines

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