
    J,                         S SK r S SKrS SKrS SKJr  S SKr S SKrS SKJr  S r
S r " S S\5      r\R                  S 5       rS	 rg! \	 a    SrSr N3f = f)
    N)_utils)patcherc                  h   ^ U4S jnT(       d  U (       d  U$ [        U 5      S:X  a  U" U S   5      $ U$ )a(  Acquires & releases a read lock around call into decorated method.

NOTE(harlowja): if no attribute name is provided then by default the
attribute named '_lock' is looked for (this attribute is expected to be
a :py:class:`.ReaderWriterLock`) in the instance object this decorator
is attached to.
c                 p   >^ ^ TR                  SS5      m[        R                  " T 5      UU 4S j5       nU$ )Nlock_lockc                    > [        U T5      nUR                  5          T" U /UQ70 UD6sS S S 5        $ ! , (       d  f       g = fN)getattr	read_lockselfargskwargsrw_lock	attr_namefs       !lib/third_party/fasteners/lock.pywrapper/read_locked.<locals>.decorator.<locals>.wrapper2   s9    dI.G""$/// %$$	   4
Agetsixwrapsr   r   r   r   s   ` @r   	decoratorread_locked.<locals>.decorator/   4    JJvw/		1	0 
	0
        r   lenr   r   r   s    ` r   read_lockedr%   &   5    	 Tt9>T!W%%r    c                  h   ^ U4S jnT(       d  U (       d  U$ [        U 5      S:X  a  U" U S   5      $ U$ )a0  Acquires & releases a write lock around call into decorated method.

NOTE(harlowja): if no attribute name is provided then by default the
attribute named '_lock' is looked for (this attribute is expected to be
a :py:class:`.ReaderWriterLock` object) in the instance object this
decorator is attached to.
c                 p   >^ ^ TR                  SS5      m[        R                  " T 5      UU 4S j5       nU$ )Nr   r   c                    > [        U T5      nUR                  5          T" U /UQ70 UD6sS S S 5        $ ! , (       d  f       g = fr
   )r   
write_lockr   s       r   r   0write_locked.<locals>.decorator.<locals>.wrapperQ   s9    dI.G##%/// &%%r   r   r   s   ` @r   r   write_locked.<locals>.decoratorN   r   r    r!   r   r"   r$   s    ` r   write_lockedr-   E   r&   r    c                       \ rS rSrSrSrSr\S 5       r\	R                  S4S jr\S 5       rSS	 jr\S
 5       rS r\R$                  S 5       r\R$                  S 5       rSrg)ReaderWriterLockd   a  A reader/writer lock.

This lock allows for simultaneous readers to exist but only one writer
to exist for use-cases where it is useful to have such types of locks.

Currently a reader can not escalate its read lock to a write lock and
a writer can not acquire a read lock while it is waiting on the write
lock.

In the future these restrictions may be relaxed.

This can be eventually removed if http://bugs.python.org/issue8800 ever
gets accepted into the python standard threading library...
wrc                      [         b2  [        b+  [        R                  " S5      (       a  [         R                  $ [        R
                  $ )Nthread)eventleteventlet_patcheris_monkey_patched
getcurrent	threadingcurrent_thread r    r   _fetch_current_thread_functor.ReaderWriterLock._fetch_current_thread_functorz   s9     $4$@11(;;***'''r    Nc                     S U l         [        R                  " 5       U l        0 U l        U" 5       U l        Uc  U R                  5       nX l        g r
   )_writercollectionsdeque_pending_writers_readers_condr<   _current_thread)r   condition_clscurrent_thread_functors      r   __init__ReaderWriterLock.__init__   sG      + 1 1 3"_
!)%)%G%G%I"5r    c                 ,    [        U R                  5      $ )z@Returns if there are writers waiting to become the *one* writer.)boolrB   r   s    r   has_pending_writers$ReaderWriterLock.has_pending_writers   s     D))**r    c                 p    U R                  5       nU R                  U:X  a  gU(       a  X R                  ;   $ g)z?Returns if the caller is the active writer or a pending writer.TF)rE   r?   rB   )r   check_pendingmes      r   	is_writerReaderWriterLock.is_writer   s4    !!#<<2....r    c                 p    U R                   b  U R                  $ U R                  (       a  U R                  $ g)z9Returns whether the lock is locked by a writer or reader.N)r?   WRITERrC   READERrL   s    r   ownerReaderWriterLock.owner   s,     <<#;;==;;r    c                 >    U R                  5       nXR                  ;   $ )z,Returns if the caller is one of the readers.)rE   rC   )r   rQ   s     r   	is_readerReaderWriterLock.is_reader   s    !!#]]""r    c              #     #    U R                  5       nXR                  ;   a  [        SU-  5      eU R                      U R                  b  U R                  U:X  a!   U R
                  U   S-   U R
                  U'   OU R                  R                  5         MZ  SSS5         U v   U R                      U R
                  U   nUS:  a  US-
  U R
                  U'   OU R
                  R                  U5         U R                  R                  5         SSS5        g! [         a    SU R
                  U'    Nf = f! , (       d  f       N= f! [         a     N_f = f! , (       d  f       g= f! U R                      U R
                  U   nUS:  a  US-
  U R
                  U'   O,U R
                  R                  U5        O! [         a     Of = fU R                  R                  5         SSS5        f ! , (       d  f       f = f= f7f)zContext manager that grants a read lock.

Will wait until no active or pending writers.

Raises a ``RuntimeError`` if a pending writer tries to acquire
a read lock.
zFWriter %s can not acquire a read lock while waiting for the write lockNr!   )
rE   rB   RuntimeErrorrD   r?   rC   KeyErrorwaitpop
notify_all)r   rQ   me_instancess      r   r   ReaderWriterLock.read_lock   s     !!#&&&  C!# $ % % ZZ <<'4<<2+=.,0MM",=,Ab) 

!  	(J #'==#4L#a',81,<b)))"- 

%%'  $ .,-b). Z4    #'==#4L#a',81,<b)))"- 

%%' s   :HD9D;D9H!E+ %H1E3'E
EE
6E	HD63D95D66D99
EH

EEEE
E($H+H8G1:'F>!G1"F>=G1>
G	G1
G	G1(	H1
G?;HHc              #   T  #    U R                  5       nU R                  SS9nU R                  5       (       a  U(       d  [        SU-  5      eU(       a  U v   gU R                     U R
                  R                  U5         [        U R                  5      S:X  a@  U R                  c3  U R
                  S   U:X  a   U R
                  R                  5       U l	        OU R                  R                  5         Mu  SSS5         U v   U R                     SU l	        U R                  R                  5         SSS5        g! , (       d  f       NJ= f! , (       d  f       g= f! U R                     SU l	        U R                  R                  5         SSS5        f ! , (       d  f       f = f= f7f)zContext manager that grants a write lock.

Will wait until no active readers. Blocks readers after acquiring.

Raises a ``RuntimeError`` if an active reader attempts to acquire
a lock.
F)rP   z4Reader %s to writer privilege escalation not allowedr   N)rE   rR   rZ   r]   rD   rB   appendr#   rC   r?   popleftr_   ra   )r   rQ   i_am_writers      r   r*   ReaderWriterLock.write_lock   s7     !!#nn5n9>>K  9;= > ? ?J%%,,R04==)Q.4<<3G003r9+/+@+@+H+H+JDL!JJOO%  ,
ZZ#'DLJJ))+  Z   ZTZZ#'DLJJ))+  ZZsg   A"F($BD:6F(?E F("E1	F(:
EF(
EF(F%)"F	F%
F"F%%F()rD   rE   rB   rC   r?   )T)__name__
__module____qualname____firstlineno____doc__rU   rV   staticmethodr<   r9   	ConditionrH   propertyrM   rR   rW   rZ   
contextlibcontextmanagerr   r*   __static_attributes__r;   r    r   r/   r/   d   s      F F
( 
(  )22(,	6 + +  #
 )( )(V , ,r    r/   c              #      #    U R                  S5      n Uv   U(       a  U R                  5         gg! U(       a  U R                  5         f f = f7f)zDAttempts to acquire a lock, and auto releases if acquired (on exit).FN)acquirerelease)r   
was_lockeds     r   try_lockrx      sB      e$JLLN :LLN s   A2 AAAc                  h   ^ U4S jnT(       d  U (       d  U$ [        U 5      S:X  a  U" U S   5      $ U$ )a  A locking **method** decorator.

It will look for a provided attribute (typically a lock or a list
of locks) on the first argument of the function decorated (typically this
is the 'self' object) and before executing the decorated function it
activates the given lock or list of locks as a context manager,
automatically releasing that lock on exit.

NOTE(harlowja): if no attribute name is provided then by default the
attribute named '_lock' is looked for (this attribute is expected to be
the lock/list of locks object/s) in the instance object this decorator
is attached to.

NOTE(harlowja): a custom logger (which will be used if lock release
failures happen) can be provided by passing a logger instance for keyword
argument ``logger``.
c                    >^ ^^ TR                  SS5      mTR                  S5      m[        R                  " T 5      UU U4S j5       nU$ )Nr   r   loggerc                   > [        U T5      n[        U[        [        45      (       ap  [        R
                  " T	S9 n[        U5       H7  u  pVUR                  U5      (       a  M  [        R                  " SUS-   -  5      e   T" U /UQ70 UD6sS S S 5        $ UnU   T" U /UQ70 UD6sS S S 5        $ ! , (       d  f       g = f! , (       d  f       g = f)N)r{   zUnable to acquire lock %sr!   )
r   
isinstancetuplelistr   	LockStack	enumerateacquire_lockr9   ThreadError)
r   r   r   
attr_valuestackir   r   r   r{   s
          r   r   *locked.<locals>.decorator.<locals>.wrapper%  s     y1J*udm44%%V4#,Z#8$11$77"+"7"7 9CFG!e9M #N N $9 T3D3F3 54 "T3D3F3 T 54 Ts   %B3&)B3C3
C
Cr   )r   r   r   r{   r   s   ` @@r   r   locked.<locals>.decorator!  sB    JJvw/	H%	1	4 
	4 r    r!   r   r"   r$   s    ` r   lockedr     s5    &. Tt9>T!W%%r    )r@   rq   r9   	fastenersr   r   r5   r   r6   ImportErrorr%   r-   objectr/   rr   rx   r   r;   r    r   <module>r      sx   (     
 4>>W,v W,t  0[  Hs   
A	 	
AA