<s> """<STR_LIT>""" <EOL> import threading <EOL> try : <EOL> from time import monotonic as _time <EOL> except ImportError : <EOL> from time import time as _time <EOL> from pymongo . monotonic import time as _time <EOL> from pymongo . errors import ExceededMaxWaiters <EOL> class Semaphore : <EOL> def __init__ ( self , value = <NUM_LIT:1> ) : <EOL> if value < <NUM_LIT:0> : <EOL> raise ValueError ( "<STR_LIT>" ) <EOL> self . _cond = threading . Condition ( threading . Lock ( ) ) <EOL> self . _value = value <EOL> def acquire ( self , blocking = True , timeout = None ) : <EOL> if not blocking and timeout is not None : <EOL> raise ValueError ( "<STR_LIT>" ) <EOL> rc = False <EOL> endtime = None <EOL> self . _cond . acquire ( ) <EOL> while self . _value == <NUM_LIT:0> : <EOL> if not blocking : <EOL> break <EOL> if timeout is not None : <EOL> if endtime is None : <EOL> endtime = _time ( ) + timeout <EOL> else : <EOL> timeout = endtime - _time ( ) <EOL> if timeout <= <NUM_LIT:0> : <EOL> break <EOL> self . _cond . wait ( timeout ) <EOL> else : <EOL> self . _value = self . _value - <NUM_LIT:1> <EOL> rc = True <EOL> self . _cond . release ( ) <EOL> return rc <EOL> __enter__ = acquire <EOL> def release ( self ) : <EOL> self . _cond . acquire ( ) <EOL> self . _value = self . _value + <NUM_LIT:1> <EOL> self . _cond . notify ( ) <EOL> self . _cond . release ( ) <EOL> def __exit__ ( self , t , v , tb ) : <EOL> self . release ( ) <EOL> @ property <EOL> def counter ( self ) : <EOL> return self . _value <EOL> class BoundedSemaphore ( Semaphore ) : <EOL> """<STR_LIT>""" <EOL> def __init__ ( self , value = <NUM_LIT:1> ) : <EOL> Semaphore . __init__ ( self , value ) <EOL> self . _initial_value = value <EOL> def release ( self ) : <EOL> if self . _value >= self . _initial_value : <EOL> raise ValueError ( "<STR_LIT>" ) <EOL> return Semaphore . release ( self ) <EOL> class DummySemaphore ( object ) : <EOL> def __init__ ( self , value = None ) : <EOL> pass <EOL> def acquire ( self , blocking = True , timeout = None ) : <EOL> return True <EOL> def release ( self ) : <EOL> pass <EOL> class MaxWaitersBoundedSemaphore ( object ) : <EOL> def __init__ ( self , semaphore_class , value = <NUM_LIT:1> , max_waiters = <NUM_LIT:1> ) : <EOL> self . waiter_semaphore = semaphore_class ( max_waiters ) <EOL> self . semaphore = semaphore_class ( value ) <EOL> def acquire ( self , blocking = True , timeout = None ) : <EOL> if not self . waiter_semaphore . acquire ( False ) : <EOL> raise ExceededMaxWaiters ( ) <EOL> try : <EOL> return self . semaphore . acquire ( blocking , timeout ) <EOL> finally : <EOL> self . waiter_semaphore . release ( ) <EOL> def __getattr__ ( self , name ) : <EOL> return getattr ( self . semaphore , name ) <EOL> class MaxWaitersBoundedSemaphoreThread ( MaxWaitersBoundedSemaphore ) : <EOL> def __init__ ( self , value = <NUM_LIT:1> , max_waiters = <NUM_LIT:1> ) : <EOL> MaxWaitersBoundedSemaphore . __init__ ( <EOL> self , BoundedSemaphore , value , max_waiters ) <EOL> def create_semaphore ( max_size , max_waiters ) : <EOL> if max_size is None : <EOL> return DummySemaphore ( ) <EOL> else : <EOL> if max_waiters is None : <EOL> return BoundedSemaphore ( max_size ) <EOL> else : <EOL> return MaxWaitersBoundedSemaphoreThread ( max_size , max_waiters ) </s>
