
    ix                    L   U d Z ddlmZ ddlZddlZddlZddlZddlZddlZddl	Z	ddl
Z
ddlZddlZddlZddlmZmZ ddlmZ ddlmZ ddlmZmZ ddlmZ dd	lmZ dd
lmZ ddlmZ ddl m!Z! erddl"m#Z#m$Z$ ed         Z%dZ&dZ' e(edd          Z)e
j*        dk    oej+        ej,        v Z- e            Z.de/d<    ej0                    a1da2da3 ed           G d d                      Z4e G d d                      Z5 ed           G d d                      Z6e G d d                      Z7 G d  d!e8          Z9 G d" d#e9$          Z: G d% d&ej;                  Z<dd'dCd/Z=dd'dDd1Z>dEd5Z?dd'dFd:Z@dd'dGd;ZAdd'dGd<ZBdHd>ZCdId?ZDdJd@ZEdJdAZFdJdBZGd#gZHdS )KzZCross-process and cross-host reader/writer lock built on :class:`SoftFileLock` primitives.    )annotationsN)contextmanagersuppress)	dataclass)Path)TYPE_CHECKINGLiteral)WeakValueDictionary)AcquireReturnProxy)Timeout)SoftFileLock)ensure_directory_exists)Callable	Generator)readwritez.breaki   
O_NOFOLLOWwin32,WeakValueDictionary[Path, SoftReadWriteLock]_all_instancesFT)frozenc                  .    e Zd ZU ded<   ded<   ded<   dS )_Pathsstrstater   readersN__name__
__module____qualname____annotations__     X/usr/local/lib/hermes-agent/venv/lib/python3.11/site-packages/filelock/_soft_rw/_sync.pyr   r   -   s+         JJJJJJLLLLLr#   r   c                  .    e Zd ZU ded<   ded<   ded<   dS )_Locksthreading.Lockinternaltransactionr   r   Nr   r"   r#   r$   r&   r&   4   s6         r#   r&   c                  .    e Zd ZU ded<   ded<   ded<   dS )_MarkerInfor   tokenintpidhostnameNr   r"   r#   r$   r+   r+   ;   s+         JJJHHHMMMMMr#   r+   c                  d    e Zd ZU dZded<   ded<   ded<   ded	<   d
ed<   ded<   ded<   ded<   dS )_HoldzYEverything that exists only while a lock is held; ``None`` when the instance has no lock.r-   level_Modemode
int | Nonewrite_thread_idr   marker_namebool	is_readerr,   _HeartbeatThreadheartbeat_threadthreading.Eventheartbeat_stopN)r   r   r    __doc__r!   r"   r#   r$   r1   r1   B   sl         ccJJJKKKOOOJJJ&&&&######r#   r1   c                  H     e Zd ZU ded<   ded<   	 dddddd	d
d fdZ xZS )_SoftRWMetar   
_instancesr'   _instances_lockT      >@N      ?blockingis_singletonheartbeat_intervalstale_thresholdpoll_interval	lock_filestr | os.PathLike[str]timeoutfloatrG   r8   rH   rI   rJ   float | NonerK   returnSoftReadWriteLockc          
        |s(t                                          |||||||          S t          |                                          }| j        5  | j                            |          }	|	3t                                          |||||||          }	|	| j        |<   n=|	j        |k    s|	j        |k    r'd|	j         d|	j         d| d| }
t          |
          |	cd d d            S # 1 swxY w Y   d S )NrF   z$Singleton lock created with timeout=z, blocking=z, cannot be changed to timeout=)
super__call__r   resolverB   rA   getrN   rG   
ValueError)clsrL   rN   rG   rH   rI   rJ   rK   
normalizedinstancemsg	__class__s              r$   rU   z_SoftRWMeta.__call__T   s     		77##!)#5 /+ $    )__,,..
  	 	~))*55H 77++%!-'9$3"/ ,   .6z**!W,,0AX0M0MT8;K T TX`Xi T T5<T TIQT T  !oo%'	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	s   BC//C36C3rC   )rL   rM   rN   rO   rG   r8   rH   r8   rI   rO   rJ   rP   rK   rO   rQ   rR   )r   r   r    r!   rU   __classcell__r]   s   @r$   r@   r@   P   s|         <<<<####
 *
 !$((,#* * * * * * * * * * * *r#   r@   c                  Z   e Zd ZU dZ e            Zded<    ej                    Z		 d;dddddd	d<dZ
ed=ddd>d            Zed=ddd>d            Zd=ddd?dZd=ddd?dZd@d Zd!d"dAd$Ze	 d;dddBd%            ZdCd(ZdDd)ZdEd.ZdEd/ZdFd2Zd@d3ZdGd4ZdHd6ZdId8ZdGd9Zd@d:ZdS )JrR   u
  
    Cross-process and cross-host reader/writer lock built on :class:`SoftFileLock` primitives.

    Use this class instead of :class:`~filelock.ReadWriteLock` when the lock file lives on a network
    filesystem (NFS, Lustre with ``-o flock``, HPC cluster shared storage). ``ReadWriteLock`` is backed
    by SQLite and cannot run on NFS because SQLite's ``fcntl`` locking is unreliable there.

    Layout on disk for a lock at ``foo.lock``:

    - ``foo.lock.state`` — a :class:`SoftFileLock` taken only during state transitions (microseconds).
    - ``foo.lock.write`` — writer marker; its presence means a writer is claiming or holding the lock.
    - ``foo.lock.readers/<host>.<pid>.<uuid>`` — one file per reader.

    Each marker stores a random token (``secrets.token_hex(16)``), the holder's pid, and the holder's
    hostname. A daemon heartbeat thread refreshes ``mtime`` on every held marker. A marker whose mtime
    has not advanced in ``stale_threshold`` seconds may be evicted by any process on any host, giving
    correct behavior when a compute node crashes with a lock held.

    Writer acquire is two-phase and writer-preferring: phase 1 claims ``.write`` (blocking any new
    reader), phase 2 waits for existing readers to drain. Writer starvation is impossible.

    Reentrancy, upgrade/downgrade rules, thread pinning, and singleton caching by resolved path match
    :class:`~filelock.ReadWriteLock`.

    Forking while holding a lock invalidates the inherited instance in the child so the child cannot
    double-own the lock with its parent; ``release()`` on a fork-invalidated instance is a no-op, and
    the child must re-acquire if it needs a lock.

    Trust boundary: protects against same-UID non-cooperating processes (one host or cross-host) and
    same-host different-UID users via ``0o600`` / ``0o700`` permissions. Does not protect against root
    compromise, NTP tampering on same-UID cross-host nodes, or multi-tenant mounts where hostile
    co-tenants share the UID.

    :param lock_file: path to the lock file; sidecar state/write/readers live next to it
    :param timeout: maximum wait time in seconds; ``-1`` means block indefinitely
    :param blocking: if ``False``, raise :class:`~filelock.Timeout` immediately on contention
    :param is_singleton: if ``True``, reuse existing instances for the same resolved path
    :param heartbeat_interval: seconds between heartbeat refreshes; default 30 s
    :param stale_threshold: seconds of ``mtime`` inactivity before a marker is stale; defaults to
        ``3 * heartbeat_interval``, matching etcd's ``LeaseKeepAlive`` convention
    :param poll_interval: seconds between acquire retries under contention; default 0.25 s

    .. versionadded:: 3.27.0

    r   rA   rC   TrD   NrE   rF   rL   rM   rN   rO   rG   r8   rH   rI   rJ   rP   rK   rQ   Nonec               J   |dk    rd| }t          |          ||dz  }||k    rd| d| d}t          |          |dk    rd| }t          |          t          j        |          | _        || _        || _        || _        || _        || _        t          | j         d| j         d	| j         d
          | _
        t          | j                   t          t          j                    t          j                    t          | j
        j        d                    | _        d | _        d | _        d| _        d| _        t,          5  | t.          t1          | j                                                  <   t5                       d d d            d S # 1 swxY w Y   d S )Nr   z)heartbeat_interval must be positive, got    z0stale_threshold must exceed heartbeat_interval (z <= )z$poll_interval must be positive, got z.statez.writez.readers)r   r   r   rC   rN   r(   r)   r   F)rX   osfspathrL   rN   rG   rI   rJ   rK   r   _pathsr   r&   	threadingLockr   r   _locks_readers_dir_fd_hold_fork_invalidated_closed_all_instances_lockr   r   rV   _register_hooks)	selfrL   rN   rG   rH   rI   rJ   rK   r\   s	            r$   __init__zSoftReadWriteLock.__init__   s    ""R>PRRCS//!"014O000o_ooZloooCS//!AHHHCS//! i	22%&);&5$1^+++^+++~///
 
 

 	 ///^%%!((t{0"===
 
 

 ,0#'
',"  	 	=AN4//7799:	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	s   =FFFrG   bool | NoneGenerator[None]c             #     K   |                      ||           	 dV  |                                  dS # |                                  w xY w)a  
        Context manager that acquires and releases a shared read lock.

        Falls back to instance defaults for *timeout* and *blocking* when ``None``.

        :param timeout: maximum wait time in seconds, or ``None`` to use the instance default
        :param blocking: if ``False``, raise :class:`~filelock.Timeout` immediately; ``None`` uses the instance default

        :raises RuntimeError: if a write lock is already held on this instance
        :raises Timeout: if the lock cannot be acquired within *timeout* seconds

        rv   N)acquire_readreleasert   rN   rG   s      r$   	read_lockzSoftReadWriteLock.read_lock   sR       	'H555	EEELLNNNNNDLLNNNN	   5 Ac             #     K   |                      ||           	 dV  |                                  dS # |                                  w xY w)a@  
        Context manager that acquires and releases an exclusive write lock.

        Falls back to instance defaults for *timeout* and *blocking* when ``None``.

        :param timeout: maximum wait time in seconds, or ``None`` to use the instance default
        :param blocking: if ``False``, raise :class:`~filelock.Timeout` immediately; ``None`` uses the instance default

        :raises RuntimeError: if a read lock is already held, or a write lock is held by a different thread
        :raises Timeout: if the lock cannot be acquired within *timeout* seconds

        rv   N)acquire_writer{   r|   s      r$   
write_lockzSoftReadWriteLock.write_lock   sR       	7X666	EEELLNNNNNDLLNNNNr~   r   c               2    |                      d||          S )uf  
        Acquire a shared read lock.

        If this instance already holds a read lock, the lock level is incremented (reentrant). Attempting to acquire a
        read lock while holding a write lock raises :class:`RuntimeError` (downgrade not allowed). On the 0→1
        transition a daemon heartbeat thread is started that refreshes the reader marker's ``mtime`` every
        ``heartbeat_interval`` seconds so peers on other hosts do not evict the marker as stale.

        :param timeout: maximum wait time in seconds, or ``None`` to use the instance default; ``-1`` means block
            indefinitely
        :param blocking: if ``False``, raise :class:`~filelock.Timeout` immediately when the lock is unavailable;
            ``None`` uses the instance default

        :returns: a proxy that can be used as a context manager to release the lock

        :raises RuntimeError: if a write lock is already held on this instance, if this instance was invalidated by
            :func:`os.fork`, or if :meth:`close` was called
        :raises Timeout: if the lock cannot be acquired within *timeout* seconds

        r   rv   _acquirer|   s      r$   rz   zSoftReadWriteLock.acquire_read  s    * }}VWx}@@@r#   c               2    |                      d||          S )a  
        Acquire an exclusive write lock.

        If this instance already holds a write lock from the same thread, the lock level is incremented (reentrant).
        Attempting to acquire a write lock while holding a read lock raises :class:`RuntimeError` (upgrade not
        allowed). Write locks are pinned to the acquiring thread: a different thread trying to re-enter also raises
        :class:`RuntimeError`.

        Writer acquisition runs in two phases. Phase 1 atomically claims ``<path>.write`` via ``O_CREAT | O_EXCL``,
        which immediately blocks any new reader on any host. Phase 2 waits for existing readers to drain. Writer
        starvation is impossible: new readers see ``<path>.write`` during phase 2 and wait behind the pending writer.

        :param timeout: maximum wait time in seconds, or ``None`` to use the instance default; ``-1`` means block
            indefinitely
        :param blocking: if ``False``, raise :class:`~filelock.Timeout` immediately when the lock is unavailable;
            ``None`` uses the instance default

        :returns: a proxy that can be used as a context manager to release the lock

        :raises RuntimeError: if a read lock is already held, if a write lock is held by a different thread, if this
            instance was invalidated by :func:`os.fork`, or if :meth:`close` was called
        :raises Timeout: if the lock cannot be acquired within *timeout* seconds

        r   rv   r   r|   s      r$   r   zSoftReadWriteLock.acquire_write$  s    2 }}Wg}AAAr#   c                Z   |                      d           | j        j        5  | j        r	 ddd           dS d| _        | j        Lt          t                    5  t          j        | j                   ddd           n# 1 swxY w Y   d| _        ddd           dS # 1 swxY w Y   dS )u  
        Release any held lock and release internal filesystem resources.

        Idempotent. After calling this method the instance can no longer acquire locks — subsequent acquires raise
        :class:`RuntimeError`. A fork-invalidated instance is closed without raising.
        TforceN)	r{   rm   r(   rq   rn   r   OSErrorrh   closert   s    r$   r   zSoftReadWriteLock.close?  sL    	4   [! 	, 	,| 	, 	, 	, 	, 	, 	, 	, 	,  DL#/g&& 3 3HT12223 3 3 3 3 3 3 3 3 3 3 3 3 3 3'+$	, 	, 	, 	, 	, 	, 	, 	, 	, 	, 	, 	, 	, 	, 	, 	, 	, 	,s:   	B "B B5B B	B B		
B  B$'B$Fr   r   c               h   | j         j        5  | j        rd| _        	 ddd           dS | j        }|:|r	 ddd           dS d| j         dt          |            d}t          |          |rd|_        n|xj        dz  c_        |j        dk    r	 ddd           dS d| _        ddd           n# 1 swxY w Y   |j        	                                 |j
                            | j        dz              |j        rt          |j        | j        	           dS t          |j                   dS )
a8  
        Release one level of the current lock.

        When the lock level reaches zero the heartbeat thread is stopped and the held marker file is unlinked. On a
        fork-invalidated instance (that is, the child of a :func:`os.fork` call made while the parent held a lock)
        this method is a no-op so inherited ``with`` blocks can unwind cleanly in the child.

        :param force: if ``True``, release the lock completely regardless of the current lock level

        :raises RuntimeError: if no lock is currently held and *force* is ``False``

        NzCannot release a lock on  (lock id: z) that is not heldr      g      ?rf   dir_fd)rm   r(   rp   ro   rL   idRuntimeErrorr2   r=   setr;   joinrI   r9   _unlinkr7   rn   )rt   r   holdr\   s       r$   r{   zSoftReadWriteLock.releaseP  s    [! 	 	% !
		 	 	 	 	 	 	 	
 :D| 	 	 	 	 	 	 	 	 j$.iiRPTXXiii"3'''  



a

zA~~!	 	 	 	 	 	 	 	" DJ#	 	 	 	 	 	 	 	 	 	 	 	 	 	 	, 	!!!""4+BS+H"III> 	&D$T-ABBBBBBD$%%%%%s#   B3B3AB3 B33B7:B7c                    | |||          S )a  
        Return the singleton :class:`SoftReadWriteLock` for *lock_file*.

        :param lock_file: path to the lock file; sidecar state/write/readers live next to it
        :param timeout: maximum wait time in seconds; ``-1`` means block indefinitely
        :param blocking: if ``False``, raise :class:`~filelock.Timeout` immediately when the lock is unavailable

        :returns: the singleton lock instance

        :raises ValueError: if an instance already exists for this path with different *timeout* or *blocking* values

        rv   r"   )rY   rL   rN   rG   s       r$   get_lockzSoftReadWriteLock.get_lockz  s    ( s9g9999r#   r4   r3   c                  || j         n|}|| j        n|}| j        j        5  | j        rd| j         d}t          |          | j        rd| j         d}t          |          | j        !| 	                    |          cd d d            S 	 d d d            n# 1 swxY w Y   t          j                    }|s!| j        j                            d          }nH|dk    r!| j        j                            d          }n!| j        j                            d|          }|st          | j                  d 	 | j        j        5  | j        ?| 	                    |          cd d d            | j        j                                         S 	 d d d            n# 1 swxY w Y   |dk    rd n||z   }	t!          j        d	          }
|d
k    r|                     |
|	|          \  }}n|                     |
|	|          \  }}t)          j                    }t-          | j        | j        |dt3          |           d          }| j        j        5  t5          d||d
k    rt)          j                    nd |||
||          | _        d d d            n# 1 swxY w Y   |                                 t;          |           | j        j                                         S # | j        j                                         w xY w)NzSoftReadWriteLock on z4 was invalidated by fork(); construct a new instancez has been closedFrv   rC   T)rG   rN      r   deadlinerG   zfilelock-heartbeat-x)refreshinterval
stop_eventnamer   )r2   r4   r6   r7   r9   r,   r;   r=   lock)rN   rG   rm   r(   rp   rL   r   rq   ro   _validate_reentranttimeperf_counterr)   acquirer   r{   secrets	token_hex_acquire_writer_slot_acquire_reader_slotrk   Eventr:   _refresh_markerrI   r   r1   	get_identstartr   )rt   r4   rN   rG   effective_timeouteffective_blockingr\   r   acquiredr   r,   r7   r9   r   	heartbeats                  r$   r   zSoftReadWriteLock._acquire  sF    -4ODLL.6.>T]]H[! 	6 	6% (rdnrrr"3'''| (NdnNNN"3'''z%//55	6 	6 	6 	6 	6 	6 	6 	6 &	6 	6 	6 	6 	6 	6 	6 	6 	6 	6 	6 	6 	6 	6 	6 !##! 	a{.666FFHH"$${.666EEHH{.66N_6``H 	4$.))t3'	.% : ::)33D99: : : : : : :L K#++----K *: : : : : : : : : : : : : : :  1B66ttEDU<UH%b))Ew)-)B)BH7I *C * *&YY *.)B)BH7I *C * *&Y #**J(,0%72d88777	  I % 
 
"=AW__I$7$9$9$9RV +'%.#-	 	 	

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 OO%4000K#++----DK#++----sm   ABB"B<K! F$K! K! F  K! #F $B.K! 6JK! JK! J&K! ! Lc                   | j         }|J |j        |k    rG|dk    rdnd}|dk    rdnd}d| d| j         dt          |            d| d	| d
}t	          |          |dk    rRt          j                    x}|j        k    r4d| j         dt          |            d| d|j         }t	          |          |xj        dz  c_        t          |           S )Nr   r   	downgradeupgradezCannot acquire z	 lock on r   z): already holding a z lock (z not allowed)zCannot acquire write lock on z) from thread z while it is held by thread r   r   )
ro   r4   rL   r   r   rk   r   r6   r2   r   )rt   r4   r   opposite	directionr\   curs          r$   r   z%SoftReadWriteLock._validate_reentrant  sY   z9"&&..wwfH'+v~~9IO$ O O O OBtHH O O%-O O6?O O O  s###7??y':'<'< <AUUUW W W2d88 W W"W W@D@TW W  s###

a

!t,,,,r#   r,   r   r   tuple[str, bool]c                                                      d fd}d fd}                     |||           	                      |||           n(# t          $ r t           j        j                    w xY w j        j        dfS )NrQ   r8   c                 t    j         j        5  t           j        j         j        t          j                               t           j        j                  r	 d d d            dS 	 t           j        j                   n# t          $ r Y d d d            dS w xY w	 d d d            n# 1 swxY w Y   dS )NrJ   nowFT)
rm   r   _break_stale_markerrj   r   rJ   r   _file_exists_atomic_create_markerFileExistsError)rt   r,   s   r$   try_claim_writerz@SoftReadWriteLock._acquire_writer_slot.<locals>.try_claim_writer  s:   " ! !#DK$5tG[aeajalalmmmm 122 ! ! ! ! ! ! ! ! !!)$+*;UCCCC& ! ! ! ! ! ! ! ! ! ! !! D! ! ! ! ! ! ! ! ! ! ! ! ! ! ! 4s6   AB-)BB-
BB-BB--B14B1c                 P    j         j        5  t          t                    5  t	           j        j                   d d d            n# 1 swxY w Y                        t          j                                	                                 cd d d            S # 1 swxY w Y   d S N)
rm   r   r   r   _touchrj   r   _break_stale_readersr   _any_readersr   s   r$   readers_drained_touchingzHSoftReadWriteLock._acquire_writer_slot.<locals>.readers_drained_touching   s   " / / g&& . .4;,---. . . . . . . . . . . . . . .))$)++666,,.../ / / / / / / / / / / / / / / / / /s3   BA	B	A	BA	=BB"Br   FrQ   r8   )_open_readers_dir	_wait_forr   r   rj   r   )rt   r,   r   rG   r   r   s   ``    r$   r   z&SoftReadWriteLock._acquire_writer_slot  s     	   		 		 		 		 		 		 			/ 	/ 	/ 	/ 	/ 	/ 	'(XNNN	NN3hQYNZZZZ 	 	 	DK%&&&	 { %''s   A %A;c               D                                       t          j                    j         dt	          j                      j        t          t           j	        j
                  z            d fd}                     |||           ndfS )N.rQ   r8   c                 P   j         j        5  t          j        j        j        t          j                               t          j        j                  r	 d d d            dS  t                      nt                     	 d d d            dS # 1 swxY w Y   d S )Nr   Fr   T)	rm   r   r   rj   r   rJ   r   r   r   )r   full_reader_pathreader_namert   r,   s   r$   try_claim_readerz@SoftReadWriteLock._acquire_reader_slot.<locals>.try_claim_reader  s   "  #DK$5tG[aeajalalmmmm 122 !         %)+uVLLLLL)*:EBBB                 s   AB(&BB"Br   Tr   )r   uuiduuid4hexrh   getpidrn   r   r   rj   r   r   )rt   r,   r   rG   r   r   r   r   s   ``   @@@r$   r   z&SoftReadWriteLock._acquire_reader_slot  s     	   )99BIKK99%tDK$788;FGG		 		 		 		 		 		 		 		 		 		 	'(XNNN%17G$NNr#   	predicateCallable[[], bool]c               $   	  |            rd S t          j                    }|st          | j                  |||k    rt          | j                  | j        }|!t          |t          ||z
  d                    }t          j        |           )NTg        )r   r   r   rL   rK   minmaxsleep)rt   r   r   rG   r   	sleep_fors         r$   r   zSoftReadWriteLock._wait_for,  s    	"y{{ #%%C .dn---#xdn---*I#	3x#~s+C+CDD	Jy!!!	"r#   c                Z   t          | j        j                  }t          t                    5  |                    d           d d d            n# 1 swxY w Y   t          j        | j        j                  }t          j	        |j
                  st          j        |j
                  s| j        j         d}t          |          | j        Xt          rSt          j        t!          t          dd          z  t"          z  }t          j        | j        j        |          | _        d S d S d S )Ni  )r4   zB exists but is not a directory or is a symlink; refusing to use itO_DIRECTORYr   )r   rj   r   r   r   mkdirrh   lstatstatS_ISLNKst_modeS_ISDIRr   rn   _SUPPORTS_DIR_FDO_RDONLYgetattr_O_NOFOLLOWopen)rt   readers_pathstr\   flagss        r$   r   z#SoftReadWriteLock._open_readers_dir@  sE   DK/00o&& 	+ 	+E***	+ 	+ 	+ 	+ 	+ 	+ 	+ 	+ 	+ 	+ 	+ 	+ 	+ 	+ 	+ Xdk)**<
## 	$4<
+C+C 	$[(lllCs###',<'K'"mQ"?"??+ME#%74;+>#F#FD    ('''s   AAAc                8    |                                  D ]} dS dS )NTF)_iter_reader_entries)rt   _s     r$   r   zSoftReadWriteLock._any_readersN  s)    **,, 	 	A44ur#   Generator[tuple[str, bool]]c              #    K   | j         Xt          j        | j                   5 }|D ]!}t          |j                  s|j        dfV  "	 ddd           n# 1 swxY w Y   dS t          | j        j                  }t          j        |          5 }|D ]1}t          |j                  st          ||j        z            dfV  2	 ddd           dS # 1 swxY w Y   dS )a#  
        Yield ``(name, dirfd_relative)`` pairs for every live reader marker.

        ``dirfd_relative`` is ``True`` when *name* should be passed to ``dir_fd=``-aware syscalls; ``False``
        when *name* is a full path because dirfd-relative I/O is unavailable on this platform.
        NTF)	rn   rh   scandir_is_housekeeping_namer   r   rj   r   r   )rt   itentryr   s       r$   r   z&SoftReadWriteLock._iter_reader_entriesS  s      +D011 /R / /E0<< /#j$....// / / / / / / / / / / / / / / FDK/00Z%% 	@ @ @,UZ88 @lUZ788%????@	@ 	@ 	@ 	@ 	@ 	@ 	@ 	@ 	@ 	@ 	@ 	@ 	@ 	@ 	@ 	@ 	@ 	@s#   %AAA5CCCr   c                    g }	 |                                  D ]%\  }}|                    ||r| j        nd f           &n# t          $ r Y d S w xY w|D ]\  }}t	          || j        ||           d S )N)rJ   r   r   )r   appendrn   r   r   rJ   )rt   r   namesr   dirfd_relativefds         r$   r   z&SoftReadWriteLock._break_stale_readersf  s    .0	(,(A(A(C(C W W$ndN$TD$8$8PTUVVVVW 	 	 	FF	 	` 	`HD"d6JPS\^_____	` 	`s   :? 
AAc                p   | j         j        5  | j        }|	 d d d            dS |j        }|j        }|j        r| j        nd }d d d            n# 1 swxY w Y   t          ||          }|dS |\  }}|t          j	        |j        |          sdS 	 t          ||           n# t          $ r Y dS w xY wdS )NFr   T)rm   r(   ro   r7   r,   r9   rn   _read_markerhmaccompare_digestr   FileNotFoundError)rt   r   r7   r,   r   read_resultinfo_mtimes           r$   r   z!SoftReadWriteLock._refresh_markerp  s`   [! 	F 	F:D|	F 	F 	F 	F 	F 	F 	F 	F *KJE-1^ET))F	F 	F 	F 	F 	F 	F 	F 	F 	F 	F 	F 	F 	F 	F 	F #;v>>>5"f <t24:uEE<5	;v.....  	 	 	55	ts(   AAAAB% %
B32B3c                    t          t          j                    t          j                    t          | j        j        d                    | _        d | _        d | _        d| _	        d S )NrC   rf   rg   T)
r&   rk   rl   r   rj   r   rm   ro   rn   rp   r   s    r$   _reset_after_fork_in_childz,SoftReadWriteLock._reset_after_fork_in_child  sd     ^%%!((t{0"===
 
 

 
#!%r#   r^   )rL   rM   rN   rO   rG   r8   rH   r8   rI   rO   rJ   rP   rK   rO   rQ   rb   r   )rN   rP   rG   rw   rQ   rx   )rN   rP   rG   rw   rQ   r   rQ   rb   )r   r8   rQ   rb   )rL   rM   rN   rO   rG   r8   rQ   rR   )r4   r3   rN   rP   rG   rw   rQ   r   )r4   r3   rQ   r   )r,   r   r   rP   rG   r8   rQ   r   )r   r   r   rP   rG   r8   rQ   rb   r   )rQ   r   )r   rO   rQ   rb   )r   r   r    r>   r
   rA   r!   rk   rl   rB   ru   r   r}   r   rz   r   r   r{   classmethodr   r   r   r   r   r   r   r   r   r   r   r  r"   r#   r$   rR   rR      s        , ,\ @S?R?T?TJTTTT$in&&O
 0
 !$((,#0 0 0 0 0 0d QU      ^& RV      ^&ATX A A A A A A.BUY B B B B B B6, , , ," (- (& (& (& (& (& (&T  :
 : : : : : [:*D. D. D. D.L- - - -(&( &( &( &(PO O O O4" " " "(G G G G   
@ @ @ @&` ` ` `   .& & & & & &r#   rR   )	metaclassc                  (     e Zd Zd fdZddZ xZS )r:   r   r   r   rO   r   r<   r   r   rQ   rb   c                x    t                                          |d           || _        || _        || _        d S )NT)r   daemon)rT   ru   _refresh	_interval_stop_event)rt   r   r   r   r   r]   s        r$   ru   z_HeartbeatThread.__init__  s>     	d4000!%r#   c                    | j                             | j                  sP|                                 s| j                                          d S | j                             | j                  Nd S d S r   )r  waitr  r  r   r   s    r$   runz_HeartbeatThread.run  sx    "''77 	==??  $$&&& "''77 	 	 	 	 	r#   )
r   r   r   rO   r   r<   r   r   rQ   rb   r  )r   r   r    ru   r  r_   r`   s   @r$   r:   r:     sQ        
& 
& 
& 
& 
& 
&       r#   r:   r   r   r   r,   r   r5   rQ   rb   c                  t           j        t           j        z  t           j        z  t          z  }t
          r|t          j        | |d|          }nt          j        | |d          }	 | dt          j                     dt          j	                     d
                    d          }t          j        ||           t          j        |           d S # t          j        |           w xY w)Ni  r   
ascii)rh   O_CREATO_EXCLO_WRONLYr   r   r   r   socketgethostnameencoder   r   )r   r,   r   r   r   contents         r$   r   r     s     J"R[0;>E )F.WT5%777WT5%((EEbikkEEV-?-A-AEEELLWUU
W
s   (AC C)'tuple[_MarkerInfo | None, float] | Nonec                  t           j        t          z  }	 t          r|t          j        | ||          nt          j        | |          }n# t
          $ r Y d S w xY w	 	 t          j        |          }t          j        |t          dz             }n%# t
          $ r Y t          j	        |           d S w xY w	 t          j	        |           n# t          j	        |           w xY wt          |          |j        fS )Nr   r   )rh   r   r   r   r   r   fstatr   _MAX_MARKER_SIZEr   _parse_marker_bytesst_mtime)r   r   r   r   r   datas         r$   r   r     s
    K+%E4DuI[RWT50000acahimotauau   tt	"B72/!344DD 	 	 	
	  	t$$bk11s;   5A 
AA1B C 
B3C 2B33C C"r"  bytes_MarkerInfo | Nonec                J   | rt          |           t          k    rd S 	 |                     d          }n# t          $ r Y d S w xY wt	          j        d|t          j                  }|d S t          |d         d          }|dk    rd S t          |d         ||d                   S )	Nr  u  
        \A                                  # start of string
        (?P<token>    [0-9a-f]{32}     ) \n # 128-bit hex token
        (?P<pid>      [1-9][0-9]{0,9}  ) \n # decimal pid: no leading zero, ≤ 10 digits
        (?P<hostname> [\x21-\x7e]{1,253})   # printable non-whitespace ASCII (RFC 1123 hostname limit)
        \n*                                 # tolerate sloppy writers that append extra newlines
        \Z                                  # end of string
        r.   
   ir,   r/   )r,   r.   r/   )	lenr  decodeUnicodeDecodeErrorrematchVERBOSEr-   r+   )r"  textr+  r.   s       r$   r   r     s      3t99///t{{7##   ttH	 	

 E }t
eElB

C
YtU7^uZ?PQQQQs   4 
AArJ   rO   r   r8   c               b   t          | |          }|dS |\  }}||z
  |k    rdS |t          | |           dS |  t           dt          j                     dt          j        d           }	 t          r|t          j        | |||           n"t          |                               |           n# t          $ r Y dS w xY wt          ||          }|dS |\  }	}
|	t          ||           dS t          j        |j        |	j                  sdS |
|k    rdS t          ||           dS )Nr   FTr   r   )
src_dir_fd
dst_dir_fd)r   r   _BREAK_SUFFIXrh   r   r   r   r   renamer   r   r   r   r,   )r   rJ   r   r   r  info_beforemtime_before
break_name
read_after
info_aftermtime_afters              r$   r   r     s    tF333Ku +K
\_,,uV$$$$tO-OO")++OO8I"8M8MOOJ 	* 2IdJ6fMMMMMJJj)))   uu j888Ju(J
6****t{0*2BCC u\!!uJv&&&&4s   0AB5 5
CCc                   t          t                    5  t          r|t          j        | |           n!t          |                                            d d d            d S # 1 swxY w Y   d S Nr   )r   r   r   rh   unlinkr   r   r   s     r$   r   r     s    	#	$	$     	  2Id6*****JJ                                   s   AA$$A(+A(c               t    t           r|t          j        | d |           d S t          j        | d            d S r:  )r   rh   utimer<  s     r$   r   r     sD     F.
tF++++++
tr#   pathc                    	 t          j        |           }n# t          $ r Y dS w xY wt          j        |j                  S )NF)rh   r   r   r   S_ISREGr   )r?  r   s     r$   r   r   &  sJ    Xd^^   uu<
###s    
%%c                >    |                      d          pt          | v S )Nr   )
startswithr1  )r   s    r$   r   r   .  s    ??38=D#88r#   c                     t          j                    at          t                                                    D ]} |                                  d S r   )rk   rl   rr   listr   valuesr  r[   s    r$   _reset_all_after_forkrH  2  sT    
 $.**..0011 . .++----. .r#   c                     t          t                                                    D ]D} t          t                    5  |                     d           d d d            n# 1 swxY w Y   Ed S )NTr   )rE  r   rF  r   	Exceptionr{   rG  s    r$   _cleanup_all_instancesrK  <  s    ..0011 ) )i   	) 	)4(((	) 	) 	) 	) 	) 	) 	) 	) 	) 	) 	) 	) 	) 	) 	)) )s   A  A$	'A$	c                     t           st          j        t                     da t          s3t          t          d          r t          j        t                     dad S d S d S )NTregister_at_fork)after_in_child)	_atexit_registeredatexitregisterrK  _fork_registeredhasattrrh   rM  rH  r"   r#   r$   rs   rs   B  sp     ".///!  ,> ? ?  
+@AAAA       r#   )r   r   r,   r   r   r5   rQ   rb   )r   r   r   r5   rQ   r  )r"  r#  rQ   r$  )
r   r   rJ   rO   r   rO   r   r5   rQ   r8   )r   r   r   r5   rQ   rb   )r?  r   rQ   r8   )r   r   rQ   r8   r  )Ir>   
__future__r   rP  r   rh   r*  r   r  r   sysrk   r   r   
contextlibr   r   dataclassesr   pathlibr   typingr   r	   weakrefr
   filelock._apir   filelock._errorr   filelock._softr   filelock._utilr   collections.abcr   r   r3   r1  r  r   r   platformr   supports_dir_fdr   r   r!   rl   rr   rO  rR  r   r&   r+   r1   typer@   rR   Threadr:   r   r   r   r   r   r   r   r   rH  rK  rs   __all__r"   r#   r$   <module>re     s   ` ` ` " " " " " "   				 				    



       / / / / / / / / ! ! ! ! ! !       ) ) ) ) ) ) ) ) ' ' ' ' ' ' , , , , , , # # # # # # ' ' ' ' ' ' 2 2 2 2 2 2 433333333 	  gb,** <7*Lrw":L/L ?R?R?T?T T T T T$in&&    $                $        
$ 
$ 
$ 
$ 
$ 
$ 
$ 
$. . . . .$ . . .bQ& Q& Q& Q& Q&+ Q& Q& Q& Q&h    y'   ( JN       59 2 2 2 2 2 2&R R R RF * * * * * *Z 04             /3      $ $ $ $9 9 9 9. . . .) ) ) )        r#   