o
    "4g\2                     @  s^  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m	Z	m
Z
mZmZ ddlmZ ddlmZ ddlmZmZmZmZ dd	lmZmZ dd
lmZ ejZejZejZ ej!Z"ejZ#ejZ$ejZ%e&e'Z(d.d/ddZ)d.d0ddZ*d.d/ddZ+d.d0ddZ,d.d/ddZ-e.edreej/ej0B ej1B eej/ej2B ej1B e ej/ej0ej2B ej1B B iZ3ni Z3d.d/dd Z4e.ed!reej5eej6e ej5ej6B iZ7ni Z7d.d/d"d#Z8d1d%d&Z9erej:Z:d'e;d(< d)ej<v rej<d) Z=e=>d*re=e? vre@d+e=e? e= ZAdS erejBd,kre9 se:ZAdS ejeCed-du r!e-ZAdS e.ed!r+e8ZAdS e)ZAdS )2z
Code concerned with waiting in different contexts (blocking, async, etc).

These functions are designed to consume the generators returned by the
`generators` module function and to return their final value.

    )annotationsN)get_event_loopwait_forEventTimeoutError)DefaultSelector   )errors)RVPQGen	PQGenConnWaitFunc)WaitReady)_psycopggen	PQGen[RV]filenointintervalfloat | Nonereturnr
   c           	   
   C  s   z?t | }t -}||| 	 |j|d}|s| t q|| |d d }| |}||| q1 s8w   Y  W dS  ty] } z|jrO|jd nd}|W  Y d}~S d}~ww )a8  
    Wait for a generator using the best strategy available.

    :param gen: a generator performing database operations and yielding
        `Ready` values when it would block.
    :param fileno: the file descriptor to wait on.
    :param interval: interval (in seconds) to check for other interrupt, e.g.
        to allow Ctrl-C. If zero or None, wait indefinitely.
    :return: whatever `!gen` returns on completion.

    Consume `!gen`, scheduling `fileno` for completion when it is reported to
    block. Once ready again send the ready state back to `!gen`.
    Ttimeoutr   r   N	nextr   registerselectsend
READY_NONE
unregisterStopIterationargs)	r   r   r   sselrlistreadyexrv r)   X/var/www/html/authentication-server/venv/lib/python3.10/site-packages/psycopg/waiting.pywait_selector%   s(   


r+   PQGenConn[RV]c           	   
   C  s   zGt | \}}|sd}t /}||| 	 |j|d}|s$| t q|| |d d }| |\}}||| q1 s@w   Y  W dS  tye } z|jrW|jd nd}|W  Y d}~S d}~ww )a  
    Wait for a connection generator using the best strategy available.

    :param gen: a generator performing database operations and yielding
        (fd, `Ready`) pairs when it would block.
    :param interval: interval (in seconds) to check for other interrupt, e.g.
        to allow Ctrl-C. If zero or None, wait indefinitely.
    :return: whatever `!gen` returns on completion.

    Behave like in `wait()`, but take the fileno to wait from the generator
    itself, which might change during processing.
    NTr   r   r   r   )	r   r   r   r#   r$   r%   r&   r'   r(   r)   r)   r*   	wait_connG   s,   

r-   c           
   
     sr  t   t }d fdd}zyt| }	 |t@ }|t@ }|s)|s)td|    d	|r8|||t	 |rA|
||t z1|d
ur\zt  |I d
H  W n ty[   Y nw   I d
H  W |rk|| |rr|| n|rz|| |r|| w w | }q ty } ztt|d
}~w ty } z|jr|jd	 nd
}	|	W  Y d
}~S d
}~ww )a  
    Coroutine waiting for a generator to complete.

    :param gen: a generator performing database operations and yielding
        `Ready` values when it would block.
    :param fileno: the file descriptor to wait on.
    :param interval: interval (in seconds) to check for other interrupt, e.g.
        to allow Ctrl-C. If None, wait indefinitely.
    :return: whatever `!gen` returns on completion.

    Behave like in `wait()`, but exposing an `asyncio` interface.
    stater   r   Nonec                   s   | O     d S Nsetr.   evr&   r)   r*   wakeup~   s   zwait_async.<locals>.wakeupTbad poll status: r   Nr.   r   r   r/   )r   r   r   WAIT_RWAIT_WeInternalErrorclear
add_readerREADY_R
add_writerREADY_Wr   waitr   remove_readerremove_writerr   OSErrorOperationalErrorstrr!   r"   )
r   r   r   loopr6   r#   readerwriterr'   r(   r)   r4   r*   
wait_asyncj   s\   



rK   c           
   
     sR  t   t }d fdd}z{t| \}}	 |t@ }|t@ }|s+|s+td|    d	|r:|||t	 |rC|
||t z/|r\zt  |I d
H  W n ty[   Y nw   I d
H  W |rk|| |rr|| n|rz|| |r|| w w | \}}q ty } z|jr|jd	 nd
}	|	W  Y d
}~S d
}~ww )a  
    Coroutine waiting for a connection generator to complete.

    :param gen: a generator performing database operations and yielding
        (fd, `Ready`) pairs when it would block.
    :param interval: interval (in seconds) to check for other interrupt, e.g.
        to allow Ctrl-C. If zero or None, wait indefinitely.
    :return: whatever `!gen` returns on completion.

    Behave like in `wait()`, but take the fileno to wait from the generator
    itself, which might change during processing.
    r.   r   r   r/   c                   s   |     d S r0   r1   r3   r4   r)   r*   r6      s   zwait_conn_async.<locals>.wakeupTr7   r   Nr8   )r   r   r   r9   r:   r;   r<   r=   r>   r?   r@   rA   r   rB   r   rC   rD   r   r!   r"   )
r   r   rH   r6   r   r#   rI   rJ   r'   r(   r)   r4   r*   wait_conn_async   sV   


rL   c              
   C  s   z;t | }d}|f}	 t|t@ r|n||t@ r|n|||\}}}d}	|r(t}	|r.|	tO }	|	s6| t q
| |	}q tyY }
 z|
j	rK|
j	d nd}|W  Y d}
~
S d}
~
ww )z
    Wait for a generator using select where supported.

    BUG: on Linux, can't select on FD >= 1024. On Windows it's fine.
    r)   Tr   N)
r   r   r9   r:   r?   rA   r   r   r!   r"   )r   r   r   r#   emptyfnlistrlwlxlr&   r'   r(   r)   r)   r*   wait_select   s4   


rR   EpollSelectorc              
   C  s   z`t | }|du s|dk rd}t C}t| }||| 	 ||}|s,| t q|d d }d}|tj @ r<t	}|tj
 @ rF|tO }| |}t| }||| q1 sYw   Y  W dS  ty~ }	 z|	jrp|	jd nd}
|
W  Y d}	~	S d}	~	ww )a$  
    Wait for a generator using epoll where supported.

    Parameters are like for `wait()`. If it is detected that the best selector
    strategy is `epoll` then this function will be used instead of `wait`.

    See also: https://linux.die.net/man/2/epoll_ctl

    BUG: if the connection FD is closed, `epoll.poll()` hangs. Same for
    EpollSelector. For this reason, wait_poll() is currently preferable.
    To reproduce the bug:

        export PSYCOPG_WAIT_FUNC=wait_epoll
        pytest tests/test_concurrency.py::test_concurrent_close
    Nr   g        Tr   )r   r   epoll_epoll_evmasksr   pollr   r   EPOLLOUTr?   EPOLLINrA   modifyr!   r"   )r   r   r   r#   rT   evmaskfileevsr5   r&   r'   r(   r)   r)   r*   
wait_epoll  s8   



r\   PollSelectorc              
   C  s   z[t | }|du s|dk rd}nt|d }t }t| }||| 	 ||}|s2| t q$|d d }d}|tj @ rBt	}|tj
 @ rL|tO }| |}t| }||| q% tyy }	 z|	jrk|	jd nd}
|
W  Y d}	~	S d}	~	ww )za
    Wait for a generator using poll where supported.

    Parameters are like for `wait()`.
    Nr   g     @@Tr   )r   r   r   rV   _poll_evmasksr   r   r   POLLOUTr?   POLLINrA   rY   r!   r"   )r   r   r   r#   rV   rZ   r[   r5   r&   r'   r(   r)   r)   r*   	wait_pollH  s8   


ra   boolc               
   C  s^   t jd} | r-z| drW dS W dS  ty, } ztd| W Y d}~dS d}~ww dS )z
    Detect if some greenlet library has patched the select library.

    If this is the case, avoid to use the wait_c function as it doesn't behave
    in a collaborative way.

    Currently supported: gevent.
    zgevent.monkeyr   Tz+failed to detect gevent monkey-patching: %sNF)sysmodulesgetis_module_patched	Exceptionloggerwarning)mr'   r)   r)   r*   _is_select_patchedn  s   

rk   r   rB   PSYCOPG_WAIT_FUNCwait_zHPSYCOPG_WAIT_FUNC should be the name of an available wait function; got win32SelectSelectorr0   )r   r   r   r   r   r   r   r
   )r   r,   r   r   r   r
   )r   rb   )D__doc__
__future__r   osrc   r   logging	selectorsasyncior   r   r   r   r    r	   r;   abcr
   r   r   r   _enumsr   r   _cmoduler   Rr9   Wr:   RWWAIT_RWNONEr   r?   rA   READY_RW	getLogger__name__rh   r+   r-   rK   rL   rR   hasattrEPOLLONESHOTrX   EPOLLERRrW   rU   r\   r`   r_   r^   ra   rk   wait_c__annotations__environfname
startswithglobalsImportErrorrB   platformgetattrr)   r)   r)   r*   <module>   s|    

"#==
"
-
&
