<s> """<STR_LIT>""" <EOL> try : <EOL> from py . magic import greenlet <EOL> except ImportError : <EOL> from greenlet import greenlet <EOL> from collections import deque <EOL> class TaskletExit ( SystemExit ) : pass <EOL> import __builtin__ <EOL> __builtin__ . TaskletExit = TaskletExit <EOL> class bomb ( object ) : <EOL> """<STR_LIT>""" <EOL> def __init__ ( self , exc_type = None , exc_value = None , exc_traceback = None ) : <EOL> self . type = exc_type <EOL> self . value = exc_value <EOL> self . traceback = exc_traceback <EOL> def raise_ ( self ) : <EOL> raise self . type , self . value , self . traceback <EOL> class channel ( object ) : <EOL> """<STR_LIT>""" <EOL> def __init__ ( self ) : <EOL> self . balance = <NUM_LIT:0> <EOL> self . queue = deque ( ) <EOL> def receive ( self ) : <EOL> return _scheduler . _receive ( self ) <EOL> def send ( self , data ) : <EOL> return _scheduler . _send ( self , data ) <EOL> def send_exception ( self , exp_type , * args ) : <EOL> self . send ( bomb ( exp_type , exp_type ( * args ) ) ) <EOL> def send_sequence ( self , iterable ) : <EOL> for item in iterable : <EOL> self . send ( item ) <EOL> class tasklet ( object ) : <EOL> """<STR_LIT>""" <EOL> def __init__ ( self , f = None , greenlet = None , alive = False ) : <EOL> self . greenlet = greenlet <EOL> self . func = f <EOL> self . alive = alive <EOL> self . blocked = False <EOL> self . data = None <EOL> def bind ( self , func ) : <EOL> if not callable ( func ) : <EOL> raise TypeError ( '<STR_LIT>' ) <EOL> self . func = func <EOL> def __call__ ( self , * args , ** kwargs ) : <EOL> """<STR_LIT>""" <EOL> if self . func is None : <EOL> raise TypeError ( '<STR_LIT>' ) <EOL> def _func ( * _args , ** _kwargs ) : <EOL> try : <EOL> self . func ( * args , ** kwargs ) <EOL> except TaskletExit : <EOL> pass <EOL> except : <EOL> import logging <EOL> logging . exception ( '<STR_LIT>' ) <EOL> finally : <EOL> assert _scheduler . current == self <EOL> _scheduler . remove ( self ) <EOL> if _scheduler . _runnable : <EOL> self . greenlet . parent = _scheduler . _runnable [ <NUM_LIT:0> ] . greenlet <EOL> self . alive = False <EOL> del self . greenlet <EOL> del self . func <EOL> del self . data <EOL> self . greenlet = greenlet ( _func ) <EOL> self . alive = True <EOL> _scheduler . append ( self ) <EOL> return self <EOL> def kill ( self ) : <EOL> _scheduler . throw ( self , TaskletExit ) <EOL> def raise_exception ( self , * args ) : <EOL> _scheduler . throw ( self , * args ) <EOL> def __str__ ( self ) : <EOL> return repr ( self ) <EOL> def __repr__ ( self ) : <EOL> if hasattr ( self , '<STR_LIT:name>' ) : <EOL> _id = self . name <EOL> else : <EOL> _id = str ( self . func ) <EOL> return '<STR_LIT>' % ( _id , id ( self ) ) <EOL> class scheduler ( object ) : <EOL> def __init__ ( self ) : <EOL> self . _main_task = tasklet ( greenlet = greenlet . getcurrent ( ) , alive = True ) <EOL> self . _runnable = deque ( [ self . _main_task ] ) <EOL> def schedule ( self ) : <EOL> """<STR_LIT>""" <EOL> self . _runnable . rotate ( - <NUM_LIT:1> ) <EOL> next_task = self . _runnable [ <NUM_LIT:0> ] <EOL> next_task . greenlet . switch ( ) <EOL> def schedule_block ( self ) : <EOL> """<STR_LIT>""" <EOL> self . _runnable . popleft ( ) <EOL> next_task = self . _runnable [ <NUM_LIT:0> ] <EOL> next_task . greenlet . switch ( ) <EOL> def throw ( self , task , * args ) : <EOL> if not task . alive : return <EOL> assert task . blocked or task in self . _runnable <EOL> task . greenlet . parent = self . _runnable [ <NUM_LIT:0> ] . greenlet <EOL> if task . blocked : <EOL> self . _runnable . appendleft ( task ) <EOL> else : <EOL> self . _runnable . remove ( task ) <EOL> self . _runnable . appendleft ( task ) <EOL> task . greenlet . throw ( * args ) <EOL> def _receive ( self , channel ) : <EOL> if channel . queue : <EOL> channel . balance -= <NUM_LIT:1> <EOL> sender = channel . queue . popleft ( ) <EOL> sender . blocked = False <EOL> self . _runnable . append ( sender ) <EOL> data , sender . data = sender . data , None <EOL> else : <EOL> current = self . _runnable [ <NUM_LIT:0> ] <EOL> channel . queue . append ( current ) <EOL> channel . balance -= <NUM_LIT:1> <EOL> current . blocked = True <EOL> try : <EOL> self . schedule_block ( ) <EOL> except : <EOL> channel . queue . remove ( current ) <EOL> channel . balance += <NUM_LIT:1> <EOL> current . blocked = False <EOL> raise <EOL> data , current . data = current . data , None <EOL> if isinstance ( data , bomb ) : <EOL> data . raise_ ( ) <EOL> else : <EOL> return data <EOL> def _send ( self , channel , data ) : <EOL> if channel . queue : <EOL> channel . balance += <NUM_LIT:1> <EOL> receiver = channel . queue . popleft ( ) <EOL> receiver . data = data <EOL> receiver . blocked = False <EOL> self . _runnable . rotate ( - <NUM_LIT:1> ) <EOL> self . _runnable . appendleft ( receiver ) <EOL> self . _runnable . rotate ( <NUM_LIT:1> ) <EOL> self . schedule ( ) <EOL> else : <EOL> current = self . current <EOL> channel . queue . append ( current ) <EOL> channel . balance += <NUM_LIT:1> <EOL> current . data = data <EOL> current . blocked = True <EOL> try : <EOL> self . schedule_block ( ) <EOL> except : <EOL> channel . queue . remove ( current ) <EOL> channel . balance -= <NUM_LIT:1> <EOL> current . data = None <EOL> current . blocked = False <EOL> raise <EOL> def remove ( self , task ) : <EOL> assert task . blocked or task in self . _runnable <EOL> if task in self . _runnable : <EOL> self . _runnable . remove ( task ) <EOL> def append ( self , task ) : <EOL> assert task not in self . _runnable <EOL> self . _runnable . append ( task ) <EOL> @ property <EOL> def runcount ( self ) : <EOL> return len ( self . _runnable ) <EOL> @ property <EOL> def current ( self ) : <EOL> return self . _runnable [ <NUM_LIT:0> ] <EOL> _scheduler = scheduler ( ) <EOL> def getruncount ( ) : <EOL> return _scheduler . runcount <EOL> def getcurrent ( ) : <EOL> return _scheduler . current <EOL> def schedule ( ) : <EOL> return _scheduler . schedule ( ) </s>
