
    2i6                       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 dd
lmZ ddlmZ ej6                  Zej:                  Zej>                  Z ejB                  Z"ej6                  Z#ej:                  Z$ej>                  Z% ejL                  e'      Z(ejR                  dk7  rddZ*nddZ*d d!dZ+d d"dZ,d d!dZ-d d"dZ.d d!dZ/ e0ed      r[eejb                  ejd                  z  eejb                  ejf                  z  e ejb                  ejd                  z  ejf                  z  iZ4ni Z4d d!dZ5 e0ed      rNeejl                  eejn                  e ejl                  ejn                  z  iZ8ejl                  ejn                  z   Z9ni Z8d d!dZ:d#dZ;erejx                  Z<de=d<   dej|                  v r?ej|                  d   Z?e?j                  d      r	e? eA       vr eBde?       eA       e?   ZCyerejR                  dk7  r
 e;       se<ZCyej                   eDedd      u re/ZCy e0ed      re:ZCye+ZCy)$z
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)EventTimeoutErrorget_event_loopwait_for)DefaultSelector   )errors)RVPQGen	PQGenConnWaitFunc)Ready)Wait)_psycopgwin32c                ~    	 t        j                  |        y# t        $ r}t        j                  d      |d}~ww xY w)zC
        Raise OperationalError if the connection is lost.
        connection socket closedN)osfstat	ExceptioneOperationalError)filenoexs     N/var/www/html/secretsanta/venv/lib/python3.12/site-packages/psycopg/waiting.py_check_fd_closedr   (   s:    	IHHV 	I$$%?@bH	Is    	<7<c                     y N )r   s    r   r   r   4   s        c                   |t        d      	 t        |       }t               5 }|j                  ||       	 |j	                  |      x}s!t        |       | j                  t               6|d   d   }| j                  |      }|j                  ||       a# 1 sw Y   yxY w# t        $ r}|j                  }|cY d}~S d}~ww xY w)a  
    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.
    :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`.
    N%indefinite wait not supported anymoretimeoutr   r	   )

ValueErrornextr   registerselectr   send
READY_NONEStopIterationvalue)	genr   intervalsselrlistreadyr   rvs	            r   wait_selectorr5   8   s     @AAI 	(#LL#!$H!===$V,HHZ(aHHUOVQ' 	( 	(  	s5   B% A5BB"B% "B% %	C.C;CCc                   |t        d      	 t        |       \  }}t               5 }|j                  ||       	 |j	                  |      x}s| j                  t               +|j                  |       |d   d   }| j                  |      \  }}|j                  ||       j# 1 sw Y   yxY w# t        $ r}|j                  }|cY d}~S d}~ww xY 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.
    :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.
    Nr#   r$   r   r	   )
r&   r'   r   r(   r)   r*   r+   
unregisterr,   r-   )	r.   r/   r   r0   r1   r2   r3   r   r4   s	            r   	wait_connr8   \   s     @AAI	 
	(#LL#!$H!===HHZ(v&aHHUO	VQ' 
	( 
	(  	s5   B1 A>B%%B.*B1 .B1 1	C:CCCc                  
K   |t        d      t               
t               }d
fd}	 t        |       }	 |t        z  }|t
        z  }|s|st        j                  d|       
j                          d|r|j                  ||t               |r|j                  ||t               	 	 t        
j                         |       d{    |r|j!                  |       |r|j#                  |       	 | j%                        }7 =# t        $ r Y Fw xY w# |r|j!                  |       |r|j#                  |       w w xY w# t&        $ r}t        j(                  d      |d}~wt*        $ r}|j,                  }	|	cY d}~S d}~ww xY 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.
    :return: whatever `!gen` returns on completion.

    Behave like in `wait()`, but exposing an `asyncio` interface.
    Nr#   c                0    | z  j                          y r   setstateevr3   s    r   wakeupzwait_async.<locals>.wakeup   s    
r!   bad poll status: r   r   r>   r   returnNone)r&   r   r   r'   WAIT_RWAIT_Wr   InternalErrorclear
add_readerREADY_R
add_writerREADY_Wr   waitr   remove_readerremove_writerr*   OSErrorr   r,   r-   )r.   r   r/   loopr@   r0   readerwriterr   r4   r?   r3   s             @@r   
wait_asyncrT   ~   sw     @AA 
BD
IZFZFfoo(9!&=>>HHJE88	/"2779h777 &&v.&&v.A+  8#  &&v.&&v.   E  !;<"D 	s}   )FA>E .D D	D 9E 	D 	DD DD )EE 	F	E%%F	1F>F	?FF		Fc                  
K   |t        d      t               
t               }d
fd}	 t        |       \  }}	 |t        z  }|t
        z  }|s|st        j                  d|       
j                          d|r|j                  ||t               |r|j                  ||t               	 |r$	 t        
j                         |       d{    n
j                          d{    |r|j!                  |       |r|j#                  |       	 | j%                        \  }}7 Y# t        $ r Y Iw xY w7 Q# |r|j!                  |       |r|j#                  |       w w xY w# t&        $ r}|j(                  }	|	cY d}~S d}~ww xY 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.
    :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.
    Nr#   c                *    | j                          y r   r;   r=   s    r   r@   zwait_conn_async.<locals>.wakeup   s    
r!   rA   r   rB   )r&   r   r   r'   rE   rF   r   rG   rH   rI   rJ   rK   rL   r   rM   r   rN   rO   r*   r,   r-   )r.   r/   rQ   r@   r   r0   rR   rS   r   r4   r?   r3   s             @@r   wait_conn_asyncrW      su     @AA 
BD
I	ZFZFfoo(9!&=>>HHJE88/&rwwy(;;; '')OO&&v.&&v.IFA1  <'  $&&v.&&v.   	s   )FBE) 0D= 3D, D*D, D= )D;*D= .<E) *D, ,	D85D= 7D88D= =)E&&E) )	F
2F?F
 FF

Fc                   |t        d      	 t        |       }d}|f}	 t        j                  |t        z  r|n||t        z  r|n|||      \  }}}|r t        |       t        j                  d      d}	|rt        }	|r	|	t        z  }	| j                  |	      }{# t        $ r}
t        j                  d      |
d}
~
wt        $ r}
|
j                  }|cY d}
~
S d}
~
ww xY w)z
    Wait for a generator using select where supported.

    BUG: on Linux, can't select on FD >= 1024. On Windows it's fine.
    Nr#   r    r   r   )r&   r'   r)   rE   rF   r   r   r   rJ   rL   r*   rP   r,   r-   )r.   r   r/   r0   emptyfnlistrlwlxlr3   r   r4   s               r   wait_selectr^      s     @AAIf*%f*%	JBB  ((()CDDE A# &  E  !;<"D 	s*   BB 	C$B::CCCCEpollSelectorc                D   |t        d      	 t        |       }|dk  rd}t        j                         5 }t        |   }|j                  ||       	 |j                  |      x}s!t        |       | j                  t               5|d   d   }d}|t        j                  z  rt        }|t        j                  z  r	|t        z  }| j                  |      }t        |   }|j                  ||       # 1 sw Y   yxY w# t        $ r}	|	j                   }
|
cY d}	~	S d}	~	ww xY 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#   r           r	   )r&   r'   r)   epoll_epoll_evmasksr(   pollr   r*   r+   EPOLLINrJ   EPOLLOUTrL   modifyr,   r-   )r.   r   r/   r0   rb   evmaskfileevsr?   r3   r   r4   s              r   
wait_epollrj   -  s     @AAIa<H\\^ 	-u#A&FNN66*#(::h#777$V,HHZ(QZ]&#E'W$EHHUO'*VV, 	- 	-$  	s5   &C> B=C22C;7C> ;C> >	DDDDPollSelectorc                   |t        d      	 t        |       }|dk  rd}nt        |dz        }t        j                         }t
        |   }|j                  ||       	 |j	                  |      x}s| j                  t               *|d   d   }d}|t        j                  z  rt        }|t        j                  z  r	|t        z  }|s)|t        z  r t        |       t        j                   d      | j                  |      }t
        |   }|j#                  ||       # t$        $ r}	|	j&                  }
|
cY d}	~	S d}	~	ww xY w)za
    Wait for a generator using poll where supported.

    Parameters are like for `wait()`.
    Nr#   r   g     @@r	   r   )r&   r'   intr)   rd   _poll_evmasksr(   r*   r+   POLLINrJ   POLLOUTrL   POLL_BADr   r   r   rg   r,   r-   )r.   r   r/   r0   rd   rh   ri   r?   r3   r   r4   s              r   	wait_pollrr   g  s.    @AA#Ia<H8f,-H{{}q!ff%#yy22G2$ABEFMM!FNN" R(] ((()CDDA"1%FKK') ,  	s   DD   	E)D<6E<Ec                     t         j                  j                  d      x} r	 | j                  d      ry	 yy# t        $ r }t
        j                  d|       Y d}~yd}~ww xY w)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_patchedr   loggerwarning)mr   s     r   _is_select_patchedr{     sf     KKOOO,,q,	N""8, -
   	NNNH"MM	Ns   8 	A!AA!r   rM   PSYCOPG_WAIT_FUNCwait_zHPSYCOPG_WAIT_FUNC should be the name of an available wait function; got SelectSelector)r   rm   rC   rD   )ra   )r.   z	PQGen[RV]r   rm   r/   floatrC   r   )r.   zPQGenConn[RV]r/   r   rC   r   )rC   bool)E__doc__
__future__r   r   rt   r)   logging	selectorsasyncior   r   r   r   r    r
   r   abcr   r   r   r   _enumsr   r   _cmoduler   RrE   WrF   RWWAIT_RWNONEr+   rJ   rL   READY_RW	getLogger__name__rx   platformr   r5   r8   rT   rW   r^   hasattrEPOLLONESHOTre   rf   rc   rj   ro   rp   rn   rq   rr   r{   wait_c__annotations__environfname
startswithglobalsImportErrorrM   getattrr    r!   r   <module>r      sG   # 	 
    A A %  / / "   		
''ZZ

''
''88			8	$ <<7I!HD:z:@%P 9o&##fnn4##foo5$$v~~5GN N,^ 9n%/M
 /0HM+\( __F  "**$JJ*+EG$WY(>9
 	
 9UD
 #,,')2D2FD')5Et"LLDY' D Dr!   