
    6h5                        S SK Jr  S SKrS SKrS SKrS SKrS SKrS SKrS SKrS SK	r	SSK
Jr  SSKJrJrJrJr  SSKJr  S r\R(                  S 5       rSS
 jrSS jr " S S	5      rS rg)    )annotationsN   )_)encodingerrorpycompatutil)procutilc                 *   [         R                  " [        R                  " 5       5      n [        R
                  R                  S5      (       a)   U S[        R                  " S5      R                  -  -  n U $ U $ ! [        [        [        4 a     U $ f = f)zReturn a string which is used to differentiate pid namespaces

It's useful to detect "dead" processes and remove stale locks with
confidence. Typically it's just hostname. On modern linux, we include an
extra Linux-specific pid namespace identifier.
s   linuxs   /%xs   /proc/self/ns/pid)r   
strtolocalsocketgethostnamer   sysplatform
startswithosstatst_inoFileNotFoundErrorPermissionErrorNotADirectoryError)results    0/usr/lib/python3/dist-packages/mercurial/lock.py_getlockprefixr      s       !3!3!56F&&x00	frww';<CCCCF M6M "?4FG 	M	s   &A9 9BBc               #  ^  ^^^#    / mSm0 n S mUUU4S jn S H<  n[        [        US5      nU(       d  M  X0;  d  M$  [        R                  " U5      X'   M>      U  H  n[        R                  " X15        M     SmSv   Sm U R	                  5        H  u  p4[        R                  " X45        M     T(       a  T" TS   5        gg! [         a     NXf = f! [         a     N0f = f! Sm U R	                  5        H  u  p4[        R                  " X45        M     f ! [         a     f f = f= f7f)a(  Block signal interrupt while doing something critical

This makes sure that the code block wrapped by this context manager won't
be interrupted.

For Windows developers: It appears not possible to guard time.sleep()
from CTRL_C_EVENT, so please don't use time.sleep() to test if this is
working.
Fc                    U [        [        SS 5      :X  d  U [        [        SS 5      :X  a  [        e[        R                  e)NSIGINTCTRL_C_EVENT)getattrsignalKeyboardInterruptr   SignalInterrupt)nums    r   raiseinterrupt)_delayedinterrupt.<locals>.raiseinterrupt>   s<    '&(D11SGND=
 6
 $#'''    c                H   > T(       a  TR                  U 5        g T" U 5        g N)append)r"   frameassertedsigsblockedr#   s     r   	catchterm$_delayedinterrupt.<locals>.catchtermF   s    $3r%   )r   r   SIGBREAKSIGHUPSIGTERMNTr   )r   r   	getsignal
ValueErroritems)orighandlersr,   namer"   handlerr*   r+   r#   s        @@@r   _delayedinterruptr7   /   s,     LGL( 
D &$-Css.$*$4$4S$9!
	#c- $
 
 	 , 2 2 4c+ !5 |A' %  		  			 	 , 2 2 4c+ !5 		s   D-C& C& C& C :C&  D-/C 2D-
CC& CC& 
C# D-"C##D-&D**/DD*
D'$D*&D''D**D-lockc                   [        XS/UQ7SS0UD6nUR                  UR                  :X  d   eUR                  S:  d   eUR                  S:X  d   eU=R                  S-  sl        SUl        UR                  b  UR                  5         U$ )zreturn a new lock that "steal" the locking made by a source lock

This is used during local clone when reloading a repository. If we could
remove the need for this during copy clone, we could remove this function.
r   dolockFr   N)r8   fheld	acquirefn)uivfslocknamestolen_lockargskwargsnew_locks          r   
steal_lockrE   r   s     C1DtDEDVDH==HJJ&&&a==AMMQMK%Or%   c                l  ^ UR                  SS5      nU4S jn[        XS/UQ7SS0UD6mU(       a	  U(       a  SOSn	Sn
U(       d  Sn
O	U(       a  Un
Sn  TR                  5          UTl        TR&                  (       a`  SU
s=::  a  TR&                  ::  a+  O  O(U R                  [)        S
5      TR&                  -  5        OU R                  S
TR&                  -  5        TR*                  (       a  TR+                  5         T$ ! [        R                   Ga  nUb(  [        US5          SSS5        O! , (       d  f       O= fX:X  a  U" U R                  UR                  5        X:X  a  U" U R                  UR                  5        X;::  a  [        UR                  [        5      (       d   e[        R                  " [        R                  [        R                  " [        UR                  5      TR                   UR                  5      e["        R$                  " S	5        US	-  n SnAOSnAff = fGM  )zreturn an acquired lock or raise an a LockHeld exception

This function is responsible to issue warnings and or debug messages about
the held lock while trying to acquires it.devel_wait_sync_fileNc                V  > SU;   al  UR                  SS5      u  p#[        S5      [        R                  " TR                  5      [        R                  " U5      [        R                  " U5      4-  nO.[        S5      TR                  [        R                  " U5      4-  nU " U5        g)z=issue the usual "waiting on lock" message through any channel   :r   s5   waiting for lock on %s held by process %r on host %r
s"   waiting for lock on %s held by %r
N)splitr   r   bytestrdesc)printerlockerhostpidmsgls        r   printwarningtrylock.<locals>.printwarning   s     6>T1-IDI   (  %  &C :;  (? C 	r%   r   r:   Fwr   s   got lock after %d seconds
)popr8   _trylockr   LockHeldopendebugrN   warn
isinstancefilenamebyteserrno	ETIMEDOUTtypingcastrL   timesleepdelayr   r=   )r>   r?   r@   timeoutwarntimeoutrB   rC   devel_wait_filerS   debugidx
warningidxrf   instrR   s                @r   trylockrm      s   
 jj!7>O& 	SA==U=f=A Wq2HJ
	 
E
	JJL, AGww
%agg%GGA45?@HH3agg=>{{	H; ~~ 	*/3/ 0//  RXXt{{3"RWWdkk2!$--7777nnOOKKt}}5FFKK	  JJqMQJE'		 s1   D H0H+'D2)	H+2
E 	<C*H++H0c                      \ rS rSrSrSr      SS jrS rS rS r	S r
SS	 jrSS
 jrS rS rS rS rSS jrSrg)r8      ar  An advisory lock held by one process to control access to a set
of files.  Non-cooperating processes or incorrectly written scripts
can ignore Mercurial's locking scheme and stomp all over the
repository, so don't do that.

Typically used via localrepository.lock() to lock the repository
store (.hg/store/) or localrepository.wlock() to lock everything
else under .hg/.Nc	                `   Xl         X l        SU l        X0l        X@l        XPl        X`l        U(       a  [        U l        O[        R                  U l        / U l        U R                  5       U l        U(       a8  U R                  5       U l        U R
                  (       a  U R                  5         g g g )Nr   )r?   r;   r<   rg   	releasefnr=   rL   r7   _maybedelayedinterruptr	   nullcontextmanagerpostrelease_getpidrP   r8   rf   )	selfr?   fnamerg   rq   r=   rL   
signalsafer:   s	            r   __init__lock.__init__   s     	""	*;D'*.*A*AD'<<>DJ~~   r%   c                    U $ r'    rv   s    r   	__enter__lock.__enter__   s    r%   c                J    [        S XU4 5       5      nU R                  US9  g )Nc              3  (   #    U  H  oS L v   M
     g 7fr'   r|   ).0as     r   	<genexpr> lock.__exit__.<locals>.<genexpr>  s     G)FA4i)Fs   )success)allrelease)rv   exc_type	exc_valueexc_tbr   s        r   __exit__lock.__exit__   s%    G(v)FGGW%r%   c                    U R                   c  g U R                   S:  a!  [        R                  " S[        SS9  SU l         U R	                  5         g )Nr   z$use lock.release instead of del lock   )category
stacklevelr   )r<   warningsr\   DeprecationWarningr   r}   s    r   __del__lock.__del__  sC    99 99q=MM6+ DIr%   c                ,    [         R                  " 5       $ r'   )r
   getpidr}   s    r   ru   lock._getpid  s      r%   c                x   U R                   n  U R                  5         U R                   U-
  $ ! [        R                   aw  nUS:w  a'  [        R
                  " S5        US:  a  US-  n S nAMb  [        R                  " [        R                  UR                  U R                  UR                  5      eS nAff = f)Nr   r   )rg   rX   r   rY   rd   re   r`   ra   r^   rL   rN   )rv   rg   rl   s      r   r8   	lock.lock  s    ,,||g-->> a<JJqM{1nnOOT]]DIIt{{ s   . B9'B4/AB44B9c           	        U R                   c  Sn[        R                  " U5      eU R                   S:  a  U =R                   S-  sl         g [        R                  c  [        5       [        l        S[        R                  U R                  4-  nSnU R                   (       dl  U(       ae  US-  n U R                  5          U R                  R                  X R                  5        SU l         S S S 5        U R                   (       d	  U(       a  Me  U R                   (       dT  [        R                   " [        R"                  U R                  R%                  U R                  5      U R&                  S5      eg ! , (       d  f       N= f! [         GaG  nUR                  [        R                  :X  a  U R                  5       nUc   S nAGM7  U R                  U5      nUbT  [        R                   " [        R"                  U R                  R%                  U R                  5      U R&                  U5      e S nAGNB[)        UR*                  [,        5      (       d   e[)        UR.                  [0        5      (       d   e[        R2                  " UR                  UR.                  [4        R6                  " [,        UR*                  5      U R&                  5      eS nAff = f)Nz)cannot acquire a lock after it was stolenr   r   s   %s:%d   r%   )r<   r   ProgrammingErrorr8   _hostr   rP   rr   r?   makelockr;   OSErrorr`   EEXIST	_readlock	_testlockrY   EAGAINjoinrL   r]   r^   r_   strerrorstrLockUnavailablerb   rc   )rv   rQ   r@   retrywhyrN   s         r   rX   lock._trylock*  s   99=C((--99q=IINI::')DJtzz48844))QJE002HH%%h7 !DI 3 ))< yy ..dhhmmDFF3TYY  7 32  99,!^^-F~ !^^F3F)#nn!LL HHMM$&&1 II"	  * &cllE::::%cllC8888//		E3<<8			 #sD   /F ?-E4,F 4
F>F F K1KA(K6BKKc                n     U R                   R                  U R                  5      $ ! [         a     gf = f)z{read lock and return its value

Returns None if no lock exists, pid for old-style locks, and host:pid
for new-style locks.
N)r?   readlockr;   r   r}   s    r   r   lock._readlockZ  s2    	88$$TVV,,  		s   $' 
44c                    Uc  g UR                  SS5      u  p#U[        R                  :w  a  g [	        U5      n[
        R                  " U5      (       a  gg! [         a     gf = f! [         a     gf = f)NFrI   r   T)rJ   r2   r8   r   intr
   testpid)rv   rN   rO   rP   s       r   _lockshouldbebrokenlock._lockshouldbebrokene  s    >	T1-ID 4::	c(C C    		  		s"   A A( 
A%$A%(
A54A5c                   U R                  U5      (       d  U$  [        U R                  U R                  S-   SS9   U R	                  5       nU R                  U5      (       d  UsS S S 5        $ U R                  R                  U R                  5        S S S 5        g ! , (       d  f       g = f! [        R                   a    Us $ f = f)Ns   .breakr   )rg   )r   r8   r?   r;   r   unlinkr   	LockErrorrv   rN   s     r   r   lock._testlockv  s    ''//M	dhh 2A>)//77! ?> '	 ?>>
  	M	s:   "B- (B$	B- .%BB- 
B*&B- *B- -CCc                D    U R                  5       nU R                  U5      $ )a?  return id of locker if lock is valid, else None.

If old-style lock, we cannot tell what machine locker is on.
with new-style lock, if locker is on this machine, we can
see if locker is alive.  If locker is on this machine but
not alive, we can safely break lock.

The lock file is only deleted when None is returned.

)r   r   r   s     r   testlocklock.testlock  s     !~~f%%r%   c                r   U R                   c  Sn[        R                  " U5      eU R                   S:  a  U =R                   S-  sl         gU R                   S:X  a  SU l         U R                  5       U R                  :w  a  g U R
                  (       a  U R                  5          U R                  R                  U R                  5        U R                   H  nU" U5        M     SU l
        gg! [         a     N0f = f!  U R                  R                  U R                  5        f ! [         a     f f = f= f)zrelease the lock and execute callback function if any

If the lock has been acquired multiple times, the actual release is
delayed to the last release call.Nz)cannot release a lock after it was stolenr   r   )r<   r   r   ru   rP   rq   r?   r   r;   r   rt   )rv   r   rQ   callbacks       r   r   lock.release  s    
 99=C((--99q=IINIYY!^DI||~)>>NN$HHOODFF+
 !,,! -  $D%   HHOODFF+ sB   !C> %%C. .
C;:C;>D6 %D&%D6&
D30D62D33D6)rr   r=   rf   rL   r;   r<   rP   rt   rq   rg   r?   )rU   NNNTT)returnr   )r   None)T)__name__
__module____qualname____firstlineno____doc__r   ry   r~   r   r   ru   r8   rX   r   r   r   r   r   __static_attributes__r|   r%   r   r8   r8      s_    " E !:&$! .`	"&$r%   c                 @    U  H  nUc  M  UR                  5         M     g r'   )r   )locksr8   s     r   r   r     s    LLN r%   )r   r8   )
__future__r   
contextlibr`   r   r   r   rd   rb   r   i18nr    r   r   r   r	   utilsr
   r   contextmanagerr7   rE   rm   r8   r   r|   r%   r   <module>r      sr    #   	          ?( ?(D$EPc$ c$Lr%   