<s> import heapq <EOL> import operator <EOL> import threading <EOL> import six <EOL> from . util import nanotime <EOL> from . sched import ( tasklet , schedule , schedule_remove , get_scheduler , <EOL> getcurrent , taskwakeup , getmain ) <EOL> from . channel import channel <EOL> class Timers ( object ) : <EOL> __slots__ = [ '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' ] <EOL> __shared_state__ = dict ( <EOL> _timers = { } , <EOL> _heap = [ ] , <EOL> _timerproc = None <EOL> ) <EOL> def __init__ ( self ) : <EOL> self . __dict__ = self . __shared_state__ <EOL> self . _lock = threading . RLock ( ) <EOL> self . sleeping = False <EOL> def add ( self , t ) : <EOL> with self . _lock : <EOL> self . _add_timer ( t ) <EOL> if self . sleeping : <EOL> self . sleeping = False <EOL> taskwakeup ( self . _timerproc ) <EOL> if self . _timerproc is None or not self . _timerproc . alive : <EOL> self . _timerproc = tasklet ( self . timerproc ) ( ) <EOL> def _add_timer ( self , t ) : <EOL> if not t . interval : <EOL> return <EOL> heapq . heappush ( self . _heap , t ) <EOL> def remove ( self , t ) : <EOL> with self . _lock : <EOL> try : <EOL> del self . _heap [ operator . indexOf ( self . _heap , t ) ] <EOL> except ( KeyError , IndexError ) : <EOL> pass <EOL> def timerproc ( self ) : <EOL> while True : <EOL> self . _lock . acquire ( ) <EOL> while True : <EOL> if not len ( self . _heap ) : <EOL> delta = - <NUM_LIT:1> <EOL> break <EOL> t = heapq . heappop ( self . _heap ) <EOL> now = nanotime ( ) <EOL> delta = t . when - now <EOL> if delta > <NUM_LIT:0> : <EOL> heapq . heappush ( self . _heap , t ) <EOL> break <EOL> else : <EOL> if t . period is not None and t . period > <NUM_LIT:0> : <EOL> np = nanotime ( t . period ) <EOL> t . when += np * ( <NUM_LIT:1> - delta / np ) <EOL> heapq . heappush ( self . _heap , t ) <EOL> self . _lock . release ( ) <EOL> t . callback ( now , t , * t . args , ** t . kwargs ) <EOL> self . _lock . acquire ( ) <EOL> if delta < <NUM_LIT:0> : <EOL> self . sleeping = True <EOL> self . _lock . release ( ) <EOL> schedule_remove ( ) <EOL> else : <EOL> self . _lock . release ( ) <EOL> schedule ( ) <EOL> timers = Timers ( ) <EOL> add_timer = timers . add <EOL> remove_timer = timers . remove <EOL> class Timer ( object ) : <EOL> def __init__ ( self , callback , interval = None , period = None , args = None , <EOL> kwargs = None ) : <EOL> if not six . callable ( callback ) : <EOL> raise ValueError ( "<STR_LIT>" ) <EOL> self . callback = callback <EOL> self . interval = interval <EOL> self . period = period <EOL> self . args = args or [ ] <EOL> self . kwargs = kwargs or { } <EOL> self . when = <NUM_LIT:0> <EOL> self . active = False <EOL> def start ( self ) : <EOL> global timers <EOL> self . active = True <EOL> self . when = nanotime ( ) + nanotime ( self . interval ) <EOL> add_timer ( self ) <EOL> def stop ( self ) : <EOL> remove_timer ( self ) <EOL> self . active = False <EOL> def __lt__ ( self , other ) : <EOL> return self . when < other . when <EOL> __cmp__ = __lt__ <EOL> def sleep ( seconds = <NUM_LIT:0> ) : <EOL> if not seconds : <EOL> return <EOL> sched = get_scheduler ( ) <EOL> curr = getcurrent ( ) <EOL> c = channel ( ) <EOL> def ready ( now , t ) : <EOL> c . send ( None ) <EOL> t = Timer ( ready , seconds ) <EOL> t . start ( ) <EOL> c . receive ( ) </s>
