<s> import threading <EOL> from collections import deque <EOL> from greenlet import getcurrent <EOL> from pulsar import get_event_loop , Future <EOL> from . utils import MustBeInChildGreenlet <EOL> class GreenLock : <EOL> """<STR_LIT>""" <EOL> def __init__ ( self , loop = None ) : <EOL> self . _loop = loop or get_event_loop ( ) <EOL> self . _local = threading . local ( ) <EOL> self . _local . locked = None <EOL> self . _queue = deque ( ) <EOL> def locked ( self ) : <EOL> """<STR_LIT>""" <EOL> return self . _local . locked <EOL> def acquire ( self , timeout = None ) : <EOL> """<STR_LIT>""" <EOL> green = getcurrent ( ) <EOL> parent = green . parent <EOL> if parent is None : <EOL> raise MustBeInChildGreenlet ( '<STR_LIT>' ) <EOL> if self . _local . locked : <EOL> future = Future ( loop = self . _loop ) <EOL> self . _queue . append ( future ) <EOL> parent . switch ( future ) <EOL> self . _local . locked = green <EOL> return self . locked ( ) <EOL> def release ( self ) : <EOL> """<STR_LIT>""" <EOL> if self . _local . locked : <EOL> while self . _queue : <EOL> future = self . _queue . popleft ( ) <EOL> if not future . done ( ) : <EOL> return future . set_result ( None ) <EOL> self . _local . locked = None <EOL> else : <EOL> raise RuntimeError ( '<STR_LIT>' ) <EOL> def __enter__ ( self ) : <EOL> self . acquire ( ) <EOL> return self <EOL> def __exit__ ( self , type , value , traceback ) : <EOL> self . release ( ) </s>
