← back to Atmos Game

assets/gen/.venv/lib/python3.12/site-packages/filelock/_soft_rw/__pycache__/_sync.cpython-312.pyc

328 lines

�

c�bjR�����UdZddlmZddlZddlZddlZddlZddlZddlZddl	Z	ddl
Z
ddlZddlZddl
Z
ddlmZmZmZddlmZddlmZddlmZmZmZddlmZdd	lmZmZmZm Z m!Z!m"Z"m#Z#m$Z$dd
l%m&Z&ddl'm(Z(ddl)m*Z*m+Z+m,Z,erdd
l-m.Z.m/Z/edZ0dZ1de2d<dZ3de2d<e4edd�Z5de2d<e4edd�Z6de2d<e
jndk7xrejpejrvZ:de2d<e�Z;de2d<ejx�a=de2d<e>�Z?d e2d!<Gd"�d#e@�ZAGd$�d%eA�&�ZBGd'�d(ej��ZDdd)�d@d*�ZEdAd+�ZFdd)�dBd,�ZGdd)�dCd-�ZHdDd.�ZIdd)�dEd/�ZJdd)�									dFd0�ZKdd)�dGd1�ZLdHd2�ZMdId3�ZNdJd4�ZOed5�6�Gd7�d8��ZPeGd9�d:��ZQed5�6�Gd;�d<��ZReGd=�d>��ZSdKd?�ZTej�eT�e!eB�d%gZVy)LzZCross-process and cross-host reader/writer lock built on :class:`SoftFileLock` primitives.�)�annotationsN)�closing�contextmanager�suppress)�	dataclass)�Path)�
TYPE_CHECKING�Final�Literal)�WeakValueDictionary)�AcquireReturnProxy�_ensure_current_process�_fork_transition�_raise_grouped_errors�_register_fork_class�_register_fork_object�_register_owned_descriptor�_unregister_owned_descriptor)�Timeout)�SoftFileLock)�ensure_directory_exists�touch�	write_all)�Callable�	Generator)�read�writez.breakz
Final[str]�
_BREAK_SUFFIXiz
Final[int]�_MAX_MARKER_SIZE�
O_NOFOLLOW�_O_NOFOLLOW�
O_NONBLOCK�_O_NONBLOCK�win32zFinal[bool]�_SUPPORTS_DIR_FDz2Final[WeakValueDictionary[int, SoftReadWriteLock]]�_ALL_INSTANCES�threading.Lock�_ALL_INSTANCES_LOCKzFinal[set[Path]]�_SINGLETONS_UNDER_CONSTRUCTIONc�f��eZdZUded<ded<	ddddddd	�															d�fd
�Z�xZS)
�_SoftRWMeta�,WeakValueDictionary[Path, SoftReadWriteLock]�
_instanceszthreading.RLock�_instances_lockT�>@N��?��blocking�is_singleton�heartbeat_interval�stale_threshold�
poll_intervalc
���t�|st�|�	|||||||��St|�j	�}|j
5|jj|�}	|	��|tvrd|��}
t|
��tj�}tj|�	t�|�	|||||||��}	tj|�tj�|k7r
d}
t|
��|	|j|<nK|	j|k7s|	j|k7r-d|	j�d|	j�d|�d|��}
t!|
��|	cddd�S#tj|�wxYw#1swYyxYw)Nr1z2Singleton lock construction is already active for zOLock construction cannot continue after fork; construct a new lock in the childz$Singleton lock created with timeout=z, blocking=z, cannot be changed to timeout=)r�super�__call__r�resolver.r-�getr)�RuntimeError�os�getpid�add�discard�timeoutr2�
ValueError)
�cls�	lock_filerAr2r3r4r5r6�
normalized�instance�msg�construction_pid�	__class__s
            ��n/Users/macstudio3/Projects/atmos-game/assets/gen/.venv/lib/python3.12/site-packages/filelock/_soft_rw/_sync.pyr9z_SoftRWMeta.__call__:s����	 �!���7�#���!�)�#5� /�+�$��
��)�_�,�,�.�
�
�
 �
 ��~�~�)�)�*�5�H����!?�?�N�y�m�\�C�&�s�+�+�#%�9�9�;� �.�2�2�:�>�G�$�w�/�!��!)�%1�+=�(7�&3� 0� �H�3�:�:�:�F��9�9�;�"2�2�k�C�&�s�+�+�-5����z�*��!�!�W�,��0A�0A�X�0M�:�8�;K�;K�:L�K�X`�Xi�Xi�Wj�k5�5<�I�[��
�T��!��o�%��=!�
 ��&3�:�:�:�F��'!�
 �s&�	AE8�)E�?BE8�E5�5E8�8F������)rD�str | os.PathLike[str]rA�floatr2�boolr3rOr4rNr5�float | Noner6rN�return�SoftReadWriteLock)�__name__�
__module__�__qualname__�__annotations__r9�
__classcell__�rIs@rJr+r+6s����<�<�$�$�
�6�
�!�$(�(,�#�6�)�6��6�
�6��
6�"�6�&�6��6�
�6�6�r+c���eZdZUdZe�Zded<ej�Z		d$dddddd�															d%d	�Z
ed&d
��Ze
d'dd�d(d��Ze
d'dd�d(d
��Zd'dd�d)d�Zd'dd�d)d�Ze	d$dd�							d*d��Zd&d�Zdd�d+d�Zd,d�Z								d-d�Z										d.d�Zd/d�Z								d0d�Zd1d�Zd1d�Z								d0d�Z								d2d�Zd&d�Zd3d�Zd4d �Z d5d!�Z!d3d"�Z"d&d#�Z#y)6rRu�

    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 invalidates the inherited instance in the child so the child cannot double-own the lock with its parent;
    ``release()`` on that instance is a no-op, and the child must construct a new instance 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,r-Tr/Nr0r1c�6�tj�|_|dkrd|��}t|��|�|dz}||krd|�d|�d�}t|��|dkrd|��}t|��tj|�|_||_||_||_||_	||_
t|j
�d�|j
�d	�|j
�d
���|_t|j
�ttj �tj �t#|jj$d�
���|_d|_d|_d|_d|_t05|t2t5|�<ddd�t7|�y#1swY�xYw)Nrz)heartbeat_interval must be positive, got �z0stale_threshold must exceed heartbeat_interval (z <= �)z$poll_interval must be positive, got z.statez.writez.readers)�stater�readersrL�rA��internal�transactionr^F)r=r>�_creator_pidrB�fspathrDrAr2r4r5r6�_Paths�_pathsr�_Locks�	threading�Lockrr^�_locks�_readers_dir_fd�_readers_dir_fd_token�_hold�_closedr(r&�idr)	�selfrDrAr2r3r4r5r6rGs	         rJ�__init__zSoftReadWriteLock.__init__�s����I�I�K�����"�=�>P�=Q�R�C��S�/�!��"�0�1�4�O��0�0�D�_�DU�UY�Zl�Ym�mn�o�C��S�/�!��A��8���H�C��S�/�!� �i�i�	�2���%���&��
�);���&5���$1�����^�^�$�F�+��^�^�$�F�+��~�~�&�h�/�
���
	 ����/���^�^�%�!���(��t�{�{�0�0�"�=�
���
,0���15��"�#'��
�"���
 �'+�N�2�d�8�$�!��d�#�!�
 �s�(F�Fc��tj�at�|_tj
�|_tj�y�N)	rirjr(rr-�RLockr.r)�clear)rCs rJ�_reset_class_after_forkz)SoftReadWriteLock._reset_class_after_fork�s6��(�n�n�.��,�.���'�o�o�/���&�,�,�.rY�r2c#�K�|j||��	d��|j�y#|j�wxYw�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

        rxN)�acquire_read�release�rqrAr2s   rJ�	read_lockzSoftReadWriteLock.read_lock�s5����	
���'�H��5�	���L�L�N��D�L�L�N���A�,�A�>�Ac#�K�|j||��	d��|j�y#|j�wxYw�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

        rxN)�
acquire_writer{r|s   rJ�
write_lockzSoftReadWriteLock.write_lock�s5����	
���7�X��6�	���L�L�N��D�L�L�N�r~c�*�|jd||��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

        rrx��_acquirer|s   rJrzzSoftReadWriteLock.acquire_reads��*�}�}�V�W�x�}�@�@rYc�*�|jd||��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

        rrxr�r|s   rJr�zSoftReadWriteLock.acquire_writes��2�}�}�W�g��}�A�ArYc��||||��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

        rx�)rCrDrAr2s    rJ�get_lockzSoftReadWriteLock.get_lock9s��(�9�g��9�9rYc�<�|jtj�k7ry|jd��|jj
5|jr
	ddd�yd|_|j�|t�5|j�t|j�d|_	|jdc}|_tt�5tj|�ddd�ddd�ddd�y#1swY�xYw#1swY�xYw#1swYyxYw)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.
        NT��force)rdr=r>r{rkrbrorlrrmrr�OSError�close)rq�fds  rJr�zSoftReadWriteLock.closeOs�������	�	��+�����4�� �
�[�[�
!�
!��|�|��"�
!� �D�L��#�#�/�%�'��1�1�=�4�T�5O�5O�P�15�D�.�/3�/C�/C�T�,�B��,�!�'�*������+�(�"�
!�+�*��(�'��"�
!�sC�D�"D�?AD�C:�!D�)D�:D�?D�D	�D�DFr�c��|jtj�k7ry|jj5|j
}|�3|r
	ddd�yd|j�dt|��d�}t|��|rd|_	n|xjdzc_	|jdkDr
	ddd�yd|_ddd�jj�|jj|jdz��|jr"t!|j"|j$�	�y|j'|j(�y#1swY��xYw)
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``

        NzCannot release a lock on � (lock id: z) that is not heldr�g�?r`��dir_fd)rdr=r>rkrbrnrDrpr<�level�heartbeat_stop�set�heartbeat_thread�joinr4�	is_reader�_unlink�marker_namerl�_unlink_writer_marker_if_ours�token)rqr��holdrGs    rJr{zSoftReadWriteLock.releasefs������	�	��+��
�[�[�
!�
!��:�:�D��|���	"�
!�
2�$�.�.�1A��R�PT�X�J�Vh�i��"�3�'�'����
��
�
�a��
��z�z�A�~��"�
!��D�J�"�"	
�����!����"�"�4�+B�+B�S�+H�"�I��>�>��D�$�$�T�-A�-A�B��.�.�t�z�z�:�-"�
!�s�E�AE�3E�Ec�P�|jj5t|jj�x}�
	ddd�y|\}}|� tj|j|�s
	ddd�yt|jj�ddd�y#1swYyxYwrt)	rkr^�_read_markerrgr�hmac�compare_digestr�r�)rqr�r�info�_s     rJr�z/SoftReadWriteLock._unlink_writer_marker_if_ours�s����[�[�
�
�$�T�[�[�%6�%6�7�7��@���
��G�D�!��|�4�#6�#6�t�z�z�5�#I���
�
�D�K�K�%�%�&�
�
�
�s�#B�(B�4B�B%c���|jtj�k7rd|j�d�}t	|��|�|j
n|}|�|jn|}|jj5|jrd|j�d�}t	|��|j�|j|�cddd�S	ddd�tj�}|s'|jjjd��}nS|dk(r'|jjjd��}n'|jjjd|��}|st!|j�d�	|j#||||��|jjj%�S#1swY��xYw#|jjj%�wxYw)	NzSoftReadWriteLock on z4 was invalidated by fork(); construct a new instancez has been closedFrxrLT)r2rA)rdr=r>rDr<rAr2rkrbrorn�_validate_reentrant�time�perf_counterrc�acquirer�_do_acquire_innerr{)rq�moderAr2rG�start�acquireds       rJr�zSoftReadWriteLock._acquire�s�������	�	��+�)�$�.�.�)9�9m�n�C��s�#�#�")�/�$�,�,�w��$,�$4�4�=�=�(��
�[�[�
!�
!��|�|�-�d�n�n�-=�=M�N��"�3�'�'��z�z�%��/�/��5�"�
!�&�	"��!�!�#����{�{�.�.�6�6��6�F�H�
��]��{�{�.�.�6�6��6�E�H��{�{�.�.�6�6��g�6�V�H���$�.�.�)�t�3�	.��)�)�$����)�R��K�K�#�#�+�+�-�'"�
!��&
�K�K�#�#�+�+�-�s�3AF,�3F8�,F5�8&Gc���|jj5|j�|j|�cddd�S	ddd�|dk(rdn||z}t	j
d�}|dk(r|j
|||��\}}n|j|||��\}}tj�}	t|j|j|	dt|�d����}
|jj5td||dk(rtj�nd||||
|	�	�|_ddd�|
j!�t#|�
�S#1swY��xYw#1swY�2xYw)NrL�r��deadliner2zfilelock-heartbeat-�x)�refresh�interval�
stop_event�namer�)r�r��write_thread_idr�r�r�r�r���lock)rkrbrnr��secrets�	token_hex�_acquire_writer_slot�_acquire_reader_slotri�Event�_HeartbeatThread�_refresh_markerr4rp�_Hold�	get_identr�r
)rqr��effective_timeoutr�r2r�r�r�r�r��	heartbeats           rJr�z#SoftReadWriteLock._do_acquire_inner�sM���[�[�
!�
!��z�z�%��/�/��5�"�
!�%�"�-��2�4��@Q�8Q���!�!�"�%���7�?�%)�%>�%>�u�x�bj�%>�%k�"�K��%)�%>�%>�u�x�bj�%>�%k�"�K���_�_�&�
�$��(�(��,�,�!�&�r�$�x��l�3�	
�	��[�[�
!�
!����9=���	� 3� 3� 5�d�'�#��!*�)�	�D�J�"�	����!�t�,�,�9"�
!�� "�
!�s�E�62E�E�E"c���|j}|�J�|j|k7rB|dk(rdnd}|dk(rdnd}d|�d|j�dt|��d|�d	|�d
�}t	|��|dk(rYtj�x}|jk7r6d|j�dt|��d|�d
|j��}t	|��|xjdz
c_t|��S)Nrr�	downgrade�upgradezCannot acquire z	 lock on r�z): already holding a z lock (z
 not allowed)zCannot acquire write lock on z) from thread z while it is held by thread r�r�)
rnr�rDrpr<rir�r�r�r
)rqr�r��opposite�	directionrG�curs       rJr�z%SoftReadWriteLock._validate_reentrant�s���z�z�������9�9���"&�&�.�w�f�H�'+�v�~��9�I�!�$��y����0@��B�t�H�:�V%�%-�J�g�i�[�
�O�
��s�#�#��7�?�y�':�':�'<� <���AU�AU�U�/����/?�{�2�d�8�*�U�"�e�#?��@T�@T�?U�W�
��s�#�#��
�
�a��
�!�t�,�,rYc�����j�d��fd�}d��fd�}�j|||��	�j|||���jj
dfS#t$r�j���wxYw)Nc�~���jj5�j��cddd�S#1swYyxYwrt)rkr^�_claim_writer_marker�rqr�s��rJ�try_claim_writerz@SoftReadWriteLock._acquire_writer_slot.<locals>.try_claim_writers*������"�"��0�0��7�#�"�"�s�3�<c����jj5�j��s�j��s
	ddd�y�j	tj
���j
�cddd�S#1swYyxYw�NF)rkr^�_touch_writer_marker_if_oursr��_break_stale_readersr��_any_readersr�s��rJ�readers_drained_touchingzHSoftReadWriteLock._acquire_writer_slot.<locals>.readers_drained_touchingsj������"�"��8�8��?��Ha�Ha�bg�Hh� �	#�"�
�)�)�$�)�)�+�6��,�,�.�.�
#�"�"�s�$B�3B�Br�F�rQrO)�_open_readers_dir�	_wait_forrr�rgr)rqr�r�r2r�r�s``    rJr�z&SoftReadWriteLock._acquire_writer_slot�s����	
��� �	8�	/�	
���'�(�X��N�	��N�N�3�h�QY�N�Z��{�{� � �%�'�'���	�
�.�.�u�5��		�s�A"�"A>c� �t|jj|jt	j���t|jj�ry	t
|jj|�y#t$rYywxYw)N�r5�nowFT)�_break_stale_markerrgrr5r��_file_exists�_atomic_create_marker�FileExistsErrorr�s  rJr�z&SoftReadWriteLock._claim_writer_markersq��	�D�K�K�-�-�t�?S�?S�Y]�Yb�Yb�Yd�e�����)�)�*��	�!�$�+�+�"3�"3�U�;����	��	�s�  B�	B
�B
c�@�t|jj�}|�y		tj|t
dz�}t|�}|� tj|j|�s	tj|�ytt�5t|jj|��ddd�	tj|�y#t$rYtj|�ywxYw#1swY�DxYw#tj|�wxYw)NFr��r�T)�_open_markerrgrr=rrr�r��_parse_marker_bytesr�r�r�rr)rqr�r��datar�s     rJr�z.SoftReadWriteLock._touch_writer_marker_if_ours's����$�+�+�+�+�
,��
�:��	�
��w�w�r�#3�a�#7�8��'�t�,�D��|�4�#6�#6�t�z�z�5�#I��

�H�H�R�L�	�'�"��d�k�k�'�'�B�/�#���H�H�R�L���
��
�H�H�R�L�
��
#�"��
�H�H�R�L�sG�C�-D�D�"C:�7D�	C7�D�6C7�7D�:D�?D�Dc�T�������j�tj�j�dt	j
�����j�tt�jj��z��d�����fd�}�j|||�����dfS�dfS)N�.c�f���jj5t�jj�j
t
j���t�jj�r
	ddd�y��t�����nt���	ddd�y#1swYyxYw)Nr�Fr�T)	rkr^r�rgrr5r�r�r�)r��full_reader_path�reader_namerqr�s�����rJ�try_claim_readerz@SoftReadWriteLock._acquire_reader_slot.<locals>.try_claim_readerHs�������"�"�#�D�K�K�$5�$5�t�G[�G[�ae�aj�aj�al�m����� 1� 1�2� �#�"��%�)�+�u�V�L�)�*:�E�B��#�"�"�s�AB'�B'�'B0r�Tr�)r��uuid�uuid4�hexr=r>rl�strrrgr_r�)rqr�r�r2r�r�r�r�s``   @@@rJr�z&SoftReadWriteLock._acquire_reader_slot<s����	
��� �����)�)�*�!�B�I�I�K�=�9���%�%���t�D�K�K�$7�$7�8�;�F�G��		�		�	
���'�(�X��N�%�1��$�N�N�7G�$�N�NrYc��	|�rytj�}|st|j��|�||k\rt|j��|j}|�t|t
||z
d��}tj|���)Ng)r�r�rrDr6�min�max�sleep)rq�	predicater�r2r��	sleep_fors      rJr�zSoftReadWriteLock._wait_forVs�����{���#�#�%�C���d�n�n�-�-��#��x���d�n�n�-�-��*�*�I��#��	�3�x�#�~�s�+C�D�	��J�J�y�!�rYc
��t|jj�}tt�5|jd��ddd�t
j|jj�}tj|j�stj|j�s$|jj�d�}t|��|j��trt�5t
j |jjtj"t%tdd�zt&z�}	t)|�}||_
||_ddd�yyy#1swY��(xYw#t*$r?}	t
j,|��#t*$r}t/d||�Yd}~�d}~wwxYwd}~wwxYw#1swYyxYw)Ni�)r�zB exists but is not a directory or is a symlink; refusing to use it�O_DIRECTORYrz>reader directory registration and descriptor close both failed)rrgr_rr��mkdirr=�lstat�stat�S_ISLNK�st_mode�S_ISDIRr<rlr%r�open�O_RDONLY�getattrr!r�
BaseExceptionr�rrm)rq�readers_path�strGr�r��registration_error�close_errors        rJr�z#SoftReadWriteLock._open_readers_dirjsm���D�K�K�/�/�0��
�o�
&����E��*�'��X�X�d�k�k�)�)�
*���<�<��
�
�#�4�<�<��
�
�+C��[�[�(�(�)�)k�l�C��s�#�#����'�,<�!�#��W�W�T�[�[�0�0�"�+�+���M�[\�@]�2]�`k�2k�l���6�r�:�E�(*��$�-2��*�$�#�-=�'�'�
&��%�	���������
)��-�\�.�'���
��
��	��	$�#�s`�E(�1AG�E5�G�(E2�5	F=�?F�F8�	F5�
F0�+F8�0F5�5F8�8F=�=G�G	c��t|j��5}|D]}ddd�y	ddd�y#1swYyxYw)NTF)r�_iter_reader_entries)rq�entriesr�s   rJr�zSoftReadWriteLock._any_readers�s=��
�T�.�.�0�
1�W����2�
1��2��2��s�5�5�>c#��K�|j�Wtj|j�5}|D](}t|j�r�|jdf���*	ddd�yt|jj�}tj|�5}|D]4}t|j�r�t||jz�df���6	ddd�y#1swYyxYw#1swYyxYw�w)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.

        A consumer that stops early must close this generator: while suspended it holds the ``scandir`` handle open,
        and leaving that to the collector surfaces as an unraisable exception inside whatever runs next.
        NTF)	rlr=�scandir�_is_housekeeping_namer�rrgr_r�)rq�it�entryrs    rJrz&SoftReadWriteLock._iter_reader_entries�s��������+����D�0�0�1�R��E�0����<�#�j�j�$�.�.� �2�
��D�K�K�/�/�0��
�Z�Z��
%����,�U�Z�Z�8��l�U�Z�Z�7�8�%�?�?��&�
%�
2�
��
%�
%�s@�,C6�C�
C�=C6�C*�6C*�	C6�C'�#C6�*C3�/C6c�"�g}	t|j��5}|D]&\}}|j||r|jndf��(	ddd�|D]\}}t||j||��� y#1swY�-xYw#t$rYywxYw)N)r5r�r�)rr�appendrlr�r�r5)rqr��namesrr��dirfd_relativer�s       rJr�z&SoftReadWriteLock._break_stale_readers�s���.0��	���2�2�4�5��,3�(�D�.��L�L�$���(<�(<�TX�!Y�Z�-4�6�
�H�D�"���d�6J�6J�PS�\^�_��6�5���	��	�s(�B�,A6�
B�6A?�;B�	B�
Bc���|jj5|j}|�
	ddd�y|j}|j}|j
r|jnd}ddd�	t��}		t|�}t|�}|� tj|j�s	tj|�yt!t�5t#||��ddd�	tj|�y#1swY��xYw#t$rYyt$rYywxYw#t$rYtj|�ywxYw#1swY�ixYw#tj|�wxYw)NFr�Tr�)rkrbrnr�r�r�rl�_open_marker_fd�FileNotFoundErrorr��_read_marker_fdr=r�r�r�r�rr)rqr�r�r�r�r�r�r�s        rJr�z!SoftReadWriteLock._refresh_marker�s7��
�[�[�
!�
!��:�:�D��|��"�
!��*�*�K��J�J�E�-1�^�^�T�)�)��F�
"�	� ��V�<�B�
	�
�&�r�*��'�t�,�D��|�4�#6�#6�t�z�z�5�#I��
�H�H�R�L�	�'�"��k�b�)�#���H�H�R�L�M"�
!��"!�	���	��	��
�
��
�H�H�R�L�
��#�"��
�H�H�R�L�sp�D�2D�+
D�:D*�-E�	E�E�&E�D�	D'�D'�&D'�*	E�3E�
E�E�E�E�E1c���ttj�tj�|jj��|_d|_d|_d|_y)Nra)rhrirjrkr^rnrlrm�rqs rJ�_reset_after_fork_in_childz,SoftReadWriteLock._reset_after_fork_in_child�sH����^�^�%�!���(��+�+�#�#�
���
��
�#���%)��"rYrK)rDrMrArNr2rOr3rOr4rNr5rPr6rNrQ�None�rQrrt)rArPr2�bool | NonerQzGenerator[None])rArPr2rrQr
)rDrMrArNr2rOrQrR)r�rOrQr)r�r�rQr)r��_ModerArPr2rrQr
)
r�rr�rNr�rNr2rOrQr
)r�rrQr
)r�r�r�rPr2rOrQztuple[str, bool])r�r�rQrO)r��Callable[[], bool]r�rPr2rOrQrr�)rQzGenerator[tuple[str, bool]])r�rNrQr)$rSrTrU�__doc__rr-rVrirur.rr�classmethodrwrr}r�rzr�r�r�r{r�r�r�r�r�r�r�r�r�r�r�rr�r�rr�rYrJrRrRssx��+�Z@S�?T�J�<�T�%�i�o�o�'�O�
�1$�
�!�$(�(,�#�1$�)�1$��1$�
�1$��
1$�"�1$�&�1$��1$�
�1$�f�/��/���QU����&��RV����&A�TX�A�.B�UY�B�6��:�
�:�)�:��:�
�:�
�
:��:�*%�.(-�%;�N
'� .�� .�� .�
� .�
�
 .�D$-��$-�!�$-��	$-��
$-�
�$-�L-�( (�� (��	 (�
� (�
�
 (�D��*O��O��	O�
�O�
�
O�4"�%�"��	"�
�"�
�
"�(3�8�@�,	`�'�R*rYrR)�	metaclassc�<��eZdZ										d�fd�Zdd�Z�xZS)r�c�R��t�|�|d��||_||_||_y)NT)r��daemon)r8rr�_refresh�	_interval�_stop_event)rqr�r�r�r�rIs     �rJrrz_HeartbeatThread.__init__�s-���	���d�4��0���
�!���%��rYc���|jj|j�sR|j�s|jj	�y|jj|j�s�Qyyrt)r%�waitr$r#r�rs rJ�runz_HeartbeatThread.run�sR���"�"�'�'����7��=�=�?�� � �$�$�&���"�"�'�'����7rY)
r�rr�rNr��threading.Eventr�r�rQrr)rSrTrUrrr(rWrXs@rJr�r��s=���
&�#�
&��
&�$�	
&�
�
&�
�
&�rYr�r�c���t||��}|�y	tj|�}tj|j
�s#d|jftj|�Stj|tdz�}	tj|�t|�|jfS#t$rYtj|�ywxYw#tj|�wxYw)Nr�r�)r�r=�fstatr��S_ISREGr��st_mtimer�rrr�r�)r�r�r�rr�s     rJr�r��s���	�d�6�	*�B�	�z���
�X�X�b�\��
�|�|�B�J�J�'�����$�
	�����	�w�w�r�+�a�/�0��	������t�$�b�k�k�1�1��	���
�������	�����s*�AB3�)B3�3	C�<C�C�C�C.c�<�tj|tdz�S)Nr�)r=rrr�s rJrr	s��
�7�7�2�'�!�+�,�,rYc��tjtztz}tr|�tj
|||��Stj
||�S�Nr�)r=r�r!r#r%r�)r�r��flagss   rJrr
sF��
�K�K�+�%��3�E�2B�v�GY�2�7�7�4��v�.�s�_a�_f�_f�gk�mr�_s�srYc�<�	t||��S#t$rYywxYwr0)rr��r�r�s  rJr�r�s&����t�F�3�3������s��	�c��|rt|�tkDry	|jd�}t	j
d|tj�}|�yt|dd�}|dkDryt|d||d��S#t$rYywxYw)	N�asciiu�
        \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
        �pid�
i���r��hostname)r�r6r8)	�lenr�decode�UnicodeDecodeError�re�match�VERBOSE�int�_MarkerInfo)r��textr=r6s    rJr�r�s����3�t�9�/�/����{�{�7�#��
�H�H�	�	
�
�
�
�
�E�
�}��

�e�E�l�B�
�C�
�Y����U�7�^��u�Z�?P�Q�Q��'����s�A9�9	B�Bc��tt�5tr|�tj||��nt|�j	�ddd�y#1swYyxYwr0)rrr%r=�unlinkrr3s  rJr�r�:s=��	�#�	$��� 2��I�I�d�6�*���J����
%�	$�	$�s�:A�Ac�(�t||��x}�y|\}}||z
|kry|�t||��y|�t�dtj��dtjd���}	tr|�tj||||��nt|�j|�t||��}|�y|\}	}
|	�t||��ytj|j|	j�sy|
|kDryt||��y#t$rYywxYw)Nr�FTr�r�)�
src_dir_fd�
dst_dir_fd)r�r�rr=r>r�r�r%�renamerr�r�r�r�)r�r5r�r��read_result�info_before�mtime_before�
break_name�
read_after�
info_after�mtime_afters           rJr�r�Cs"��$�D��8�8��A�� +��K��
�\��_�,������V�$���6�-���"�)�)�+��a��8I�8I�"�8M�7N�O�J���� 2��I�I�d�J�6�f�M���J���j�)��j��8�J����(��J�����
�6�*�����{�0�0�*�2B�2B�C���\�!���J�v�&�������s�%<D�	D�Dc	��tjtjztjztz}t
r|�tj||d|��}ntj||d�}d}	tj|�}|j|jf}t||�dtj��dtj��d�jd��tj|�y#t $r4tj|�|�t#|||��r
t%||���wxYw)Ni�r��
r5)r=�O_CREAT�O_EXCL�O_WRONLYr!r%r�r+�st_dev�st_inorr>�socket�gethostname�encoder�r�
_same_filer�)r�r�r�r1r��identityrs       rJr�r�os���
�J�J����"�R�[�[�0�;�>�E��F�.�
�W�W�T�5�%��
7��
�W�W�T�5�%�
(��(,�H�
�
�X�X�b�\���9�9�b�i�i�'���"���r�"�)�)�+��b��1C�1C�1E�0F�b�I�P�P�QX�Y�Z�	������
��
�������J�t�X�f�$M��D��(�
�	�s
�6A5D�=D>c���	tr|�tj||��ntj|�}|j|j
f|k(S#t$rYywxYw)Nr�F)r%r=r�r�rTrU)r�rZr�rs    rJrYrY�s[���.>�6�CU�R�X�X�d�6�
*�[]�[c�[c�dh�[i��
�I�I�r�y�y�!�X�-�-������s�4A�	A�Ac��	tj|�}tj|j
�S#t$rYywxYwr�)r=r�rr�r,r�)�pathrs  rJr�r��s=���
�X�X�d�^���<�<��
�
�#�#������s�6�	A�Ac�8�|jd�xst|vS)Nr�)�
startswithr)r�s rJr
r
�s���?�?�3��8�=�D�#8�8rYT)�frozenc�,�eZdZUded<ded<ded<y)rfr�r^rr_N�rSrTrUrVr�rYrJrfrf�s���J��J�
�LrYrfc�,�eZdZUded<ded<ded<y)rhr'rbrcrr^Nrbr�rYrJrhrh�s�������rYrhc�,�eZdZUded<ded<ded<y)r@r�r�r?r6r8Nrbr�rYrJr@r@�s���J�	�H��MrYr@c�b�eZdZUdZded<ded<ded<ded	<d
ed<ded<d
ed<ded<y)r�zYEverything that exists only while a lock is held; ``None`` when the instance has no lock.r?r�rr��
int | Noner�r�r�rOr�r�r�r�r)r�N)rSrTrUrrVr�rYrJr�r��s1��c��J�
�K������O��J�&�&�#�#rYr�c��ttj��D],}tt�5|jd��ddd��.y#1swY�9xYw)NTr�)�listr&�valuesr�	Exceptionr{)rFs rJ�_cleanup_all_instancesrk�sB����.�.�0�1��
�i�
 ����4��(�!�
 �2�
 �
 �s�A�A	)r�r�r�rfrQz'tuple[_MarkerInfo | None, float] | None)r�r?rQ�bytes)r�r�r�rfrQr?)r�r�r�rfrQrf)r�rlrQz_MarkerInfo | None)r�r�r�rfrQr)
r�r�r5rNr�rNr�rfrQrO)r�r�r�r�r�rfrQr)r�r�rZztuple[int, int]r�rfrQrO)r]r�rQrO)r�r�rQrOr)Wr�
__future__r�atexitr�r=r<r�rVr��sysrir�r��
contextlibrrr�dataclassesr�pathlibr�typingr	r
r�weakrefr�
filelock._apir
rrrrrrr�filelock._errorr�filelock._softr�filelock._utilrrr�collections.abcrrrrrVrr�r!r#�platformr��supports_dir_fdr%r&rjr(r�r)�typer+rR�Threadr�r�rrr�r�r�r�r�rYr�r
rfrhr@r�rk�register�__all__r�rYrJ�<module>r�sV��`�"�
��	�	��
��
����8�8�!��0�0�'�	�	�	�$�'�D�D��3�	�� ��$�
�z�$�#��*�#�!�"�l�A�6��Z�6�!�"�l�A�6��Z�6�!$���� 7� Y�B�G�G�r�GY�GY�<Y��+�Y�EX�EZ��B�Z�&4�i�n�n�&6��^�6�36�5�� 0�8�:�$�:�zk	*�+�k	*�\�y�'�'��(59�2�(-�8<�t�59��R�<04� ��)�

�)��)�
�	)�

�)�
�
)�XJN��0.�$�9��$������������$�������
$�
$��
$�)�����&�'��&�'���rY