
    qi;                    b   U 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	m
Z
mZ d dlmZmZ d dlmZ ddlmZ ddlmZ erd d	lmZ  ej.                  d
      Z e       Zded<    ej8                         ZddZ ej>                  e       dZ ddZ! G d de"      Z# G d de#      Z$y)    )annotationsN)contextmanagersuppress)TYPE_CHECKINGLiteral)WeakValueDictionary   )AcquireReturnProxy)Timeout)	Generatorfilelockzset[sqlite3.Connection]_all_connectionsc                     t         5  t        t              D ]*  } t        t              5  | j                          d d d        , t        j                          d d d        y # 1 sw Y   SxY w# 1 sw Y   y xY wN)_all_connections_locklistr   r   	Exceptioncloseclear)cons    F/opt/pipecat/venv/lib/python3.12/site-packages/filelock/_read_write.py_cleanup_connectionsr      sm    	 !() 	C)$ 		 	 	 	! ! ! !s!   "A-A!A-!A*&A--A6i5wc                   |du ry| dk(  rt         S | dk  rd}t        |      | dkD  rt        | |z
  d      n| }t        |dz        }|t         kD  s|dk  r!t        j                  d| t                t         S |S )NFr   z+timeout must be a non-negative number or -1i  z7timeout %s is too large for SQLite, using %s ms instead)_MAX_SQLITE_TIMEOUT_MS
ValueErrormaxint_LOGGERwarning)timeoutblockingalready_waitedmsg	remaining
timeout_mss         r   timeout_for_sqliter'   (   s    5"}%%{;o4;aKGn,a0WIY%&J**j1nQSZ\rs%%    c                  X     e Zd ZU dZded<   ded<   	 d	ddd	 	 	 	 	 	 	 	 	 d
 fdZ xZS )_ReadWriteLockMetaa"  
    Metaclass that handles singleton resolution when is_singleton=True.

    Singleton logic lives here rather than in ReadWriteLock.get_lock so that ``ReadWriteLock(path)`` transparently
    returns cached instances without a 2-arg ``super()`` call that type checkers cannot verify.

    0WeakValueDictionary[pathlib.Path, ReadWriteLock]
_instanceszthreading.Lock_instances_lockTr"   is_singletonc          	        |st         |   ||||      S t        j                  |      j	                         }| j
                  5  || j                  vr#t         |   ||||      }|| j                  |<   n| j                  |   }|j                  |k7  s|j                  |k7  r-d|j                   d|j                   d| d| }t        |      |cd d d        S # 1 sw Y   y xY w)Nr.   z$Singleton lock created with timeout=z, blocking=z, cannot be changed to timeout=)
super__call__pathlibPathresolver-   r,   r!   r"   r   )	cls	lock_filer!   r"   r/   
normalizedinstancer$   	__class__s	           r   r2   z_ReadWriteLockMeta.__call__G   s     7#IwXd#ee\\),446
   	/ 7+Iw`l+m-5z*>>*57*h.?.?8.K:8;K;K:LKX`XiXiWj k55<I[
T  !o%	 	 	s   BCC&r   )
r7   str | os.PathLike[str]r!   floatr"   boolr/   r>   returnReadWriteLock)__name__
__module____qualname____doc____annotations__r2   __classcell__)r:   s   @r   r*   r*   ;   sc     A@##
 
 !) 
   
 r(   r*   c                  :   e Zd ZU dZ e       Zded<    ej                         Z	e
	 ddd	 	 	 	 	 	 	 dd       Z	 dddd	 	 	 	 	 	 	 	 	 ddZdd	Zdd
Z	 	 	 	 	 	 	 	 	 	 ddZddZdddddZdddddZddddZedddd d       Zedddd d       Zd!dZy)"r@   a  
    Cross-process read-write lock backed by SQLite.

    Allows concurrent shared readers or a single exclusive writer. The lock is reentrant within the same mode (multiple
    ``acquire_read`` calls nest, as do multiple ``acquire_write`` calls from the same thread), but upgrading from read
    to write or downgrading from write to read raises :class:`RuntimeError`. Write locks are pinned to the thread that
    acquired them.

    By default, ``is_singleton=True``: calling ``ReadWriteLock(path)`` with the same resolved path returns the same
    instance. The lock file must use a ``.db`` extension (SQLite database).

    :param lock_file: path to the SQLite database file used as the lock
    :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
    :param is_singleton: if ``True``, reuse existing instances for the same resolved path

    .. versionadded:: 3.21.0

    r+   r,   Tr"   c                    | |||      S )a	  
        Return the singleton :class:`ReadWriteLock` for *lock_file*.

        :param lock_file: path to the SQLite database file used as the lock
        :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

        rH    )r6   r7   r!   r"   s       r   get_lockzReadWriteLock.get_lock{   s      9g99r(   r.   c                  t        j                  |      | _        || _        || _        t        j                         | _        t        j                         | _        d| _	        d | _
        d | _        t        j                  | j                  d      | _        t        5  t         j#                  | j                         d d d        y # 1 sw Y   y xY w)Nr   F)check_same_thread)osfspathr7   r!   r"   	threadingLock_transaction_lock_internal_lock_lock_level_current_mode_write_thread_idsqlite3connect_conr   r   add)selfr7   r!   r"   r/   s        r   __init__zReadWriteLock.__init__   s     9- !*!1'nn.>B,0OODNNeL	" 	,  +	, 	, 	,s    CCc                   |s| j                   j                  d      }n?|dk(  r| j                   j                  d      }n| j                   j                  d|      }|st        | j                        d y )NFrH   r   Tr"   r!   )rR   acquirer   r7   )r[   r"   r!   acquireds       r   _acquire_transaction_lockz'ReadWriteLock._acquire_transaction_lock   sr    --55u5EH]--55t5DH--55tW5UH$..)t3 r(   c                ~   | j                   |k7  r0d| d| j                   dt        |        d| d| d}t        |      |dk(  rYt	        j
                         x}| j                  k7  r6d| j                   dt        |        d	| d
| j                   }t        |      | xj                  dz  c_        t        |       S )NzCannot acquire z	 lock on  (lock id: z): already holding a z lock (z not allowed)writezCannot acquire write lock on z) from thread z while it is held by thread r	   lock)	rU   r7   idRuntimeErrorrP   	get_identrV   rT   r
   )r[   modeopposite	directionr$   curs         r   _validate_reentrantz!ReadWriteLock._validate_reentrant   s    %!$y0@BtH: V%%-Jgi[O  s##7?y':':'< <AVAVV//?{2d8* U"e#?@U@U?VX  s##A!t,,r(   c               j   t        j                         |z
  }t        |||      }| j                  j	                  d| d      j                          | j                  j	                  d      j                          t        j                         |z
  }t        |||      x}|k7  r-| j                  j	                  d| d      j                          |dk(  rdnd}| j                  j	                  |      j                          |dk(  r*| j                  j	                  d	      j                          y y )
N)r"   r#   zPRAGMA busy_timeout=;zPRAGMA journal_mode=MEMORY;rd   zBEGIN EXCLUSIVE TRANSACTION;zBEGIN TRANSACTION;readz'SELECT name FROM sqlite_schema LIMIT 1;)timeperf_counterr'   rY   executer   )	r[   rj   r!   r"   
start_timewaitedr&   
recomputedstmts	            r   _configure_and_beginz"ReadWriteLock._configure_and_begin   s    ""$z1'(SYZ
		0A>?EEG 			78>>@""$z1,WxX^__JdnnII 4ZLBCIIK15-FZ		$%%'6> IIGHNNP r(   c                  |dk(  rdnd}|dk(  rdnd}| j                   5  | j                  dkD  r| j                  |||      cd d d        S 	 d d d        t        j                         }| j                  ||       	 | j                   5  | j                  dkD  r6| j                  |||      cd d d        | j                  j                          S 	 d d d        | j                  ||||       | j                   5  || _	        d| _        |dk(  rt        j                         | _        d d d        t        | 	      | j                  j                          S # 1 sw Y   	xY w# 1 sw Y   xY w# 1 sw Y   HxY w# t        j                  $ r)}d
t!        |      vr t#        | j$                        d d }~ww xY w# | j                  j                          w xY w)Nrq   rd   	downgradeupgrader   r^   )r"   ru   r	   re   zdatabase is locked)rS   rT   rn   rr   rs   ra   rR   releasery   rU   rP   ri   rV   r
   rW   OperationalErrorstrr   r7   )r[   rj   r!   r"   rk   rl   ru   excs           r   _acquirezReadWriteLock._acquire   s   "fn7&#'6>Ky	   	K!#//h	J	K 	K#	K &&(
&&'&J	-$$ O##a'33D(INO O& ""**,% (O %%dGhS]%^$$ B%)"#$ 7?,5,?,?,AD)	B &40 ""**,7	K 	KO OB B '' 	4#3s83$..)t3	4
 ""**,se   "E<E8 "E *	E8 )E8 8-E,%E8 E E)%E8 ,E51E8 8F4$F//F44F7 7Gc               *    | j                  d||      S )a  
        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).

        :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: 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
        :raises Timeout: if the lock cannot be acquired within *timeout* seconds

        rq   rH   r   r[   r!   r"   s      r   acquire_readzReadWriteLock.acquire_read   s      }}VWx}@@r(   c               *    | j                  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`.

        :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: a proxy that can be used as a context manager to release the lock

        :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

        rd   rH   r   r   s      r   acquire_writezReadWriteLock.acquire_write  s    $ }}Wg}AAr(   Fforcec                  d}| j                   5  | j                  dk(  r3|r
	 ddd       yd| j                   dt        |        d}t	        |      |rd| _        n| xj                  dz  c_        | j                  dk(  rd| _        d| _        d}ddd       |r| j                  j                          yy# 1 sw Y   'xY w)	al  
        Release one level of the current lock.

        When the lock level reaches zero the underlying SQLite transaction is rolled back, releasing the database lock.

        :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``

        Fr   NzCannot release a lock on rc   z) that is not heldr	   T)	rS   rT   r7   rg   rh   rU   rV   rY   rollback)r[   r   should_rollbackr$   s       r   r}   zReadWriteLock.release  s         	'1$	' 	' 2$..1ARPTXJVhi"3''#$   A% 1$%)"(,%"&	' II  	' 	's   B6A%B66B?Nc             #     K   || j                   }|| j                  }| j                  ||       	 d | j                          y# | j                          w xY w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

        NrH   )r!   r"   r   r}   r   s      r   	read_lockzReadWriteLock.read_lock8  sR      ?llG}}H'H5	LLNDLLN   0AA AAAc             #     K   || j                   }|| j                  }| j                  ||       	 d | j                          y# | j                          w xY w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

        NrH   )r!   r"   r   r}   r   s      r   
write_lockzReadWriteLock.write_lockM  sR      ?llG}}H7X6	LLNDLLNr   c                    | j                  d       | j                  j                          t        5  t        j                  | j                         ddd       y# 1 sw Y   yxY w)z
        Release the lock (if held) and close the underlying SQLite connection.

        After calling this method, the lock instance is no longer usable.

        Tr   N)r}   rY   r   r   r   discard)r[   s    r   r   zReadWriteLock.closeb  sJ     	4 		" 	0$$TYY/	0 	0 	0s    AA%r;   )r7   r<   r!   r=   r"   r>   r?   r@   )
r7   r<   r!   r=   r"   r>   r/   r>   r?   None)r"   r>   r!   r=   r?   r   )rj   Literal['read', 'write']rk   r   rl   r   r?   r
   )
rj   r   r!   r=   r"   r>   ru   r=   r?   r   )rj   r   r!   r=   r"   r>   r?   r
   )r!   r=   r"   r>   r?   r
   )r   r>   r?   r   r   )r!   zfloat | Noner"   zbool | Noner?   zGenerator[None]r?   r   )rA   rB   rC   rD   r   r,   rE   rP   rQ   r-   classmethodrK   r\   ra   rn   ry   r   r   r   r}   r   r   r   r   rJ   r(   r   r@   r@   c   sQ   ( DWCXJ@X$inn&OAC:Y]:.:9>:RV:	: :( ,
 !,), ,
 , , 
,(4- Q,Q7<QKOQ]bQ	Q2-BAD A$BT B( (- !: QU  ( RV  (
0r(   r@   )	metaclassr   )r!   r=   r"   r>   r#   r=   r?   r   )%
__future__r   atexitloggingrN   r3   rW   rP   rr   
contextlibr   r   typingr   r   weakrefr   _apir
   _errorr   collections.abcr   	getLoggerr   setr   rE   rQ   r   r   registerr   r'   typer*   r@   rJ   r(   r   <module>r      s    "   	     / ) ' $ )
'

J
',/E ) 1&	( ! $ % + &% %PI00 I0r(   