<s> from collections import deque <EOL> import operator <EOL> import threading <EOL> import time <EOL> _tls = threading . local ( ) <EOL> import greenlet <EOL> import six <EOL> from . util import thread_ident <EOL> class TaskletExit ( Exception ) : <EOL> pass <EOL> try : <EOL> import __builtin__ <EOL> __builtin__ . TaskletExit = TaskletExit <EOL> except ImportError : <EOL> import builtins <EOL> setattr ( builtins , '<STR_LIT>' , TaskletExit ) <EOL> CoroutineExit = TaskletExit <EOL> _global_task_id = <NUM_LIT:0> <EOL> def _coroutine_getcurrent ( ) : <EOL> try : <EOL> return _tls . current_coroutine <EOL> except AttributeError : <EOL> return _coroutine_getmain ( ) <EOL> def _coroutine_getmain ( ) : <EOL> try : <EOL> return _tls . main_coroutine <EOL> except AttributeError : <EOL> main = coroutine ( ) <EOL> main . _is_started = - <NUM_LIT:1> <EOL> main . _greenlet = greenlet . getcurrent ( ) <EOL> _tls . main_coroutine = main <EOL> return _tls . main_coroutine <EOL> class coroutine ( object ) : <EOL> """<STR_LIT>""" <EOL> _is_started = <NUM_LIT:0> <EOL> def __init__ ( self ) : <EOL> self . _greenlet = greenlet <EOL> def bind ( self , func , * args , ** kwargs ) : <EOL> def _run ( ) : <EOL> _tls . current_coroutine = self <EOL> self . _is_started = <NUM_LIT:1> <EOL> func ( * args , ** kwargs ) <EOL> self . _is_started = <NUM_LIT:0> <EOL> self . _greenlet = greenlet . greenlet ( _run ) <EOL> def switch ( self ) : <EOL> current = _coroutine_getcurrent ( ) <EOL> try : <EOL> self . _greenlet . switch ( ) <EOL> finally : <EOL> _tls . current_coroutine = current <EOL> def kill ( self ) : <EOL> current = _coroutine_getcurrent ( ) <EOL> if self is current : <EOL> raise CoroutineExit <EOL> self . throw ( CoroutineExit ) <EOL> def throw ( self , * args ) : <EOL> current = _coroutine_getcurrent ( ) <EOL> try : <EOL> self . _greenlet . throw ( * args ) <EOL> finally : <EOL> _tls . current_coroutine = current <EOL> @ property <EOL> def is_alive ( self ) : <EOL> return self . _is_started < <NUM_LIT:0> or bool ( self . _greenlet ) <EOL> @ property <EOL> def is_zombie ( self ) : <EOL> return self . _is_started > <NUM_LIT:0> and bool ( self . _greenlet . dead ) <EOL> getcurrent = staticmethod ( _coroutine_getcurrent ) <EOL> def _scheduler_contains ( value ) : <EOL> scheduler = get_scheduler ( ) <EOL> return value in scheduler <EOL> def _scheduler_switch ( current , next ) : <EOL> scheduler = get_scheduler ( ) <EOL> return scheduler . switch ( current , next ) <EOL> class tasklet ( coroutine ) : <EOL> """<STR_LIT>""" <EOL> tempval = None <EOL> def __new__ ( cls , func = None , label = '<STR_LIT>' ) : <EOL> res = coroutine . __new__ ( cls ) <EOL> res . label = label <EOL> res . _task_id = None <EOL> return res <EOL> def __init__ ( self , func = None , label = '<STR_LIT>' ) : <EOL> coroutine . __init__ ( self ) <EOL> self . _init ( func , label ) <EOL> def _init ( self , func = None , label = '<STR_LIT>' ) : <EOL> global _global_task_id <EOL> self . func = func <EOL> self . label = label <EOL> self . alive = False <EOL> self . blocked = False <EOL> self . sched = None <EOL> self . thread_id = thread_ident ( ) <EOL> self . _task_id = _global_task_id <EOL> _global_task_id += <NUM_LIT:1> <EOL> def __str__ ( self ) : <EOL> return '<STR_LIT>' % ( self . label , self . _task_id ) <EOL> __repr__ = __str__ <EOL> def __call__ ( self , * argl , ** argd ) : <EOL> return self . setup ( * argl , ** argd ) <EOL> def bind ( self , func ) : <EOL> """<STR_LIT>""" <EOL> if not six . callable ( func ) : <EOL> raise TypeError ( '<STR_LIT>' ) <EOL> self . func = func <EOL> def setup ( self , * argl , ** argd ) : <EOL> """<STR_LIT>""" <EOL> if self . func is None : <EOL> raise TypeError ( '<STR_LIT>' ) <EOL> func = self . func <EOL> sched = self . sched = get_scheduler ( ) <EOL> def _func ( ) : <EOL> try : <EOL> try : <EOL> func ( * argl , ** argd ) <EOL> except TaskletExit : <EOL> pass <EOL> finally : <EOL> sched . remove ( self ) <EOL> self . alive = False <EOL> self . func = None <EOL> coroutine . bind ( self , _func ) <EOL> self . alive = True <EOL> sched . append ( self ) <EOL> return self <EOL> def run ( self ) : <EOL> self . insert ( ) <EOL> _scheduler_switch ( getcurrent ( ) , self ) <EOL> def kill ( self ) : <EOL> if self . is_alive : <EOL> coroutine . kill ( self ) <EOL> schedrem ( self ) <EOL> self . alive = False <EOL> def raise_exception ( self , exc , * args ) : <EOL> if not self . is_alive : <EOL> return <EOL> schedrem ( self ) <EOL> coroutine . throw ( self , exc , * args ) <EOL> def insert ( self ) : <EOL> if self . blocked : <EOL> raise RuntimeError ( "<STR_LIT>" ) <EOL> if not self . alive : <EOL> raise RuntimeError ( "<STR_LIT>" ) <EOL> schedpush ( self ) <EOL> def remove ( self ) : <EOL> if self . blocked : <EOL> raise RuntimeError ( "<STR_LIT>" ) <EOL> if self is getcurrent ( ) : <EOL> raise RuntimeError ( "<STR_LIT>" ) <EOL> schedrem ( self ) <EOL> class Scheduler ( object ) : <EOL> def __init__ ( self ) : <EOL> self . _main_coroutine = _coroutine_getmain ( ) <EOL> self . _main_tasklet = _coroutine_getcurrent ( ) <EOL> self . _main_tasklet . __class__ = tasklet <EOL> six . get_method_function ( self . _main_tasklet . _init ) ( self . _main_tasklet , <EOL> label = '<STR_LIT>' ) <EOL> self . _last_task = self . _main_tasklet <EOL> self . thread_id = thread_ident ( ) <EOL> self . _lock = threading . Lock ( ) <EOL> self . _callback = None <EOL> self . _run_calls = [ ] <EOL> self . runnable = deque ( ) <EOL> self . blocked = <NUM_LIT:0> <EOL> self . append ( self . _main_tasklet ) <EOL> def send ( self ) : <EOL> self . _async . send ( ) <EOL> def wakeup ( self , handle ) : <EOL> self . schedule ( ) <EOL> def set_callback ( self , cb ) : <EOL> self . _callback = cb <EOL> def append ( self , value , normal = True ) : <EOL> if normal : <EOL> self . runnable . append ( value ) <EOL> else : <EOL> self . runnable . rotate ( - <NUM_LIT:1> ) <EOL> self . runnable . appendleft ( value ) <EOL> self . runnable . rotate ( <NUM_LIT:1> ) <EOL> def appendleft ( self , task ) : <EOL> self . runnable . appendleft ( task ) <EOL> def remove ( self , task ) : <EOL> """<STR_LIT>""" <EOL> with self . _lock : <EOL> try : <EOL> self . runnable . remove ( task ) <EOL> if task . blocked : <EOL> self . blocked += <NUM_LIT:1> <EOL> except ValueError : <EOL> pass <EOL> def unblock ( self , task , normal = True ) : <EOL> """<STR_LIT>""" <EOL> with self . _lock : <EOL> task . blocked = <NUM_LIT:0> <EOL> self . blocked -= <NUM_LIT:1> <EOL> self . append ( task , normal ) <EOL> def taskwakeup ( self , task ) : <EOL> if task is None : <EOL> return <EOL> with self . _lock : <EOL> try : <EOL> self . runnable . remove ( task ) <EOL> except ValueError : <EOL> pass <EOL> self . unblock ( task ) <EOL> def switch ( self , current , next ) : <EOL> prev = self . _last_task <EOL> if ( self . _callback is not None and prev is not next ) : <EOL> self . _callback ( prev , next ) <EOL> self . _last_task = next <EOL> assert not next . blocked <EOL> if next is not current : <EOL> next . switch ( ) <EOL> return current <EOL> def schedule ( self , retval = None ) : <EOL> curr = self . getcurrent ( ) <EOL> main = self . getmain ( ) <EOL> if retval is None : <EOL> retval = curr <EOL> while True : <EOL> if self . runnable : <EOL> if self . runnable [ <NUM_LIT:0> ] is curr : <EOL> self . runnable . rotate ( - <NUM_LIT:1> ) <EOL> task = self . runnable [ <NUM_LIT:0> ] <EOL> elif self . _run_calls : <EOL> task = self . _run_calls . pop ( ) <EOL> else : <EOL> raise RuntimeError ( "<STR_LIT>" ) <EOL> self . switch ( curr , task ) <EOL> if curr is self . _last_task : <EOL> return retval <EOL> def run ( self ) : <EOL> curr = self . getcurrent ( ) <EOL> self . _run_calls . append ( curr ) <EOL> self . remove ( curr ) <EOL> try : <EOL> while True : <EOL> self . schedule ( ) <EOL> if not curr . blocked : <EOL> break <EOL> time . sleep ( <NUM_LIT> ) <EOL> finally : <EOL> self . append ( curr ) <EOL> def runcount ( self ) : <EOL> return len ( self . runnable ) <EOL> def getmain ( self ) : <EOL> return self . _main_tasklet <EOL> def getcurrent ( self ) : <EOL> curr = _coroutine_getcurrent ( ) <EOL> if curr == self . _main_coroutine : <EOL> return self . _main_tasklet <EOL> else : <EOL> return curr <EOL> def __contains__ ( self , value ) : <EOL> try : <EOL> operator . indexOf ( self . runnable , value ) <EOL> return True <EOL> except ValueError : <EOL> return False <EOL> _channel_callback = None <EOL> def set_channel_callback ( channel_cb ) : <EOL> global _channel_callback <EOL> _channel_callback = channel_cb <EOL> def get_scheduler ( ) : <EOL> global _tls <EOL> try : <EOL> return _tls . scheduler <EOL> except AttributeError : <EOL> scheduler = _tls . scheduler = Scheduler ( ) <EOL> return scheduler <EOL> def taskwakeup ( task ) : <EOL> sched = get_scheduler ( ) <EOL> sched . taskwakeup ( task ) <EOL> def getruncount ( ) : <EOL> sched = get_scheduler ( ) <EOL> return sched . runcount ( ) <EOL> def getcurrent ( ) : <EOL> return get_scheduler ( ) . getcurrent ( ) <EOL> def getmain ( ) : <EOL> return get_scheduler ( ) . getmain ( ) <EOL> def set_schedule_callback ( scheduler_cb ) : <EOL> sched = get_scheduler ( ) <EOL> sched . set_callback ( scheduler_cb ) <EOL> def schedule ( retval = None ) : <EOL> scheduler = get_scheduler ( ) <EOL> return scheduler . schedule ( retval = retval ) <EOL> def schedule_remove ( retval = None ) : <EOL> scheduler = get_scheduler ( ) <EOL> scheduler . remove ( scheduler . getcurrent ( ) ) <EOL> return scheduler . schedule ( retval = retval ) <EOL> def schedpush ( task ) : <EOL> scheduler = get_scheduler ( ) <EOL> scheduler . append ( task ) <EOL> def schedrem ( task ) : <EOL> scheduler = get_scheduler ( ) <EOL> scheduler . remove ( task ) <EOL> def run ( ) : <EOL> sched = get_scheduler ( ) <EOL> sched . run ( ) <EOL> def _bootstrap ( ) : <EOL> get_scheduler ( ) <EOL> _bootstrap ( ) </s>
