o
    fr                     @   s  d Z ddlZejdkred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 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 ddlmZ ddlmZ ddlmZ dZdZdZdZdZdZdZG dd dejZ G dd dejZ!G dd de!Z"G dd de!Z#G dd de$Z%G dd  d ej&Z'G d!d" d"ej(Z)G d#d$ d$Z*G d%d& d&ej+Z,e'Z-G d'd( d(ej.Z/G d)d* d*ej.Z0e0Z1dS )+z.Selector and proactor event loops for Windows.    Nwin32z
win32 only   )events)base_subprocess)futures)
exceptions)proactor_events)selector_events)tasks)windows_utils)logger)SelectorEventLoopProactorEventLoopIocpProactorDefaultEventLoopPolicyWindowsSelectorEventLoopPolicyWindowsProactorEventLoopPolicy    i  i  gMbP?g?c                       s`   e Zd ZdZdd fdd
Z fddZdd	 Zd fd
d	Z fddZ fddZ	  Z
S )_OverlappedFuturezSubclass of Future which represents an overlapped operation.

    Cancelling it will immediately cancel the overlapped operation.
    Nloopc                   s&   t  j|d | jr| jd= || _d S Nr   )super__init___source_traceback_ov)selfovr   	__class__ -/usr/lib/python3.10/asyncio/windows_events.pyr   6   s   
z_OverlappedFuture.__init__c                    sH   t   }| jd ur"| jjrdnd}|dd| d| jjdd |S )Npending	completedr   zoverlapped=<z, #x>)r   
_repr_infor   r#   insertaddressr   infostater   r!   r"   r'   <   s
   

 z_OverlappedFuture._repr_infoc              
   C   st   | j d u rd S z| j   W n& ty4 } zd|| d}| jr$| j|d< | j| W Y d }~nd }~ww d | _ d S )Nz&Cancelling an overlapped future failedmessage	exceptionfuturesource_traceback)r   cancelOSErrorr   _loopcall_exception_handler)r   exccontextr!   r!   r"   _cancel_overlappedC   s   


	z$_OverlappedFuture._cancel_overlappedc                       |    t j|dS N)msg)r8   r   r2   r   r;   r   r!   r"   r2   S      z_OverlappedFuture.cancelc                    s   t  | |   d S N)r   set_exceptionr8   r   r/   r   r!   r"   r?   W   s   z_OverlappedFuture.set_exceptionc                    s   t  | d | _d S r>   )r   
set_resultr   r   resultr   r!   r"   rA   [   s   
z_OverlappedFuture.set_resultr>   )__name__
__module____qualname____doc__r   r'   r8   r2   r?   rA   __classcell__r!   r!   r   r"   r   0   s    r   c                       sp   e Zd ZdZdd fdd
Zdd Z fdd	Zd
d Zdd Zd fdd	Z	 fddZ
 fddZ  ZS )_BaseWaitHandleFuturez2Subclass of Future which represents a wait handle.Nr   c                   s8   t  j|d | jr| jd= || _|| _|| _d| _d S )Nr   r   T)r   r   r   r   _handle_wait_handle_registered)r   r   handlewait_handler   r   r!   r"   r   c   s   
z_BaseWaitHandleFuture.__init__c                 C   s   t | jdt jkS Nr   )_winapiWaitForSingleObjectrJ   WAIT_OBJECT_0r   r!   r!   r"   _pollq   s   z_BaseWaitHandleFuture._pollc                    sd   t   }|d| jd | jd ur!|  rdnd}|| | jd ur0|d| jd |S )Nzhandle=r%   signaledwaitingzwait_handle=)r   r'   appendrJ   rT   rK   r*   r   r!   r"   r'   v   s   



z _BaseWaitHandleFuture._repr_infoc                 C   s
   d | _ d S r>   )r   r   futr!   r!   r"   _unregister_wait_cb   s   
z)_BaseWaitHandleFuture._unregister_wait_cbc              
   C   s   | j sd S d| _ | j}d | _zt| W n3 tyH } z'|jtjkr>d|| d}| jr1| j|d< | j	| W Y d }~d S W Y d }~nd }~ww | 
d  d S NFz$Failed to unregister the wait handler-   r1   )rL   rK   _overlappedUnregisterWaitr3   winerrorERROR_IO_PENDINGr   r4   r5   rZ   r   rN   r6   r7   r!   r!   r"   _unregister_wait   s*   
z&_BaseWaitHandleFuture._unregister_waitc                    r9   r:   )ra   r   r2   r<   r   r!   r"   r2      r=   z_BaseWaitHandleFuture.cancelc                       |    t | d S r>   )ra   r   r?   r@   r   r!   r"   r?         z#_BaseWaitHandleFuture.set_exceptionc                    rb   r>   )ra   r   rA   rB   r   r!   r"   rA      rc   z _BaseWaitHandleFuture.set_resultr>   )rD   rE   rF   rG   r   rT   r'   rZ   ra   r2   r?   rA   rH   r!   r!   r   r"   rI   `   s    
rI   c                       sF   e Zd ZdZdd fdd
Zdd Z fdd	Z fd
dZ  ZS )_WaitCancelFuturezoSubclass of Future which represents a wait for the cancellation of a
    _WaitHandleFuture using an event.
    Nr   c                   s   t  j||||d d | _d S )Nr   )r   r   _done_callback)r   r   eventrN   r   r   r!   r"   r      s   
z_WaitCancelFuture.__init__c                 C   s   t d)Nz'_WaitCancelFuture must not be cancelled)RuntimeErrorrS   r!   r!   r"   r2      s   z_WaitCancelFuture.cancelc                    (   t  | | jd ur| |  d S d S r>   )r   rA   re   rB   r   r!   r"   rA         
z_WaitCancelFuture.set_resultc                    rh   r>   )r   r?   re   r@   r   r!   r"   r?      ri   z_WaitCancelFuture.set_exception)	rD   rE   rF   rG   r   r2   rA   r?   rH   r!   r!   r   r"   rd      s    rd   c                       s6   e Zd Zdd fdd
Z fddZdd Z  ZS )	_WaitHandleFutureNr   c                   s<   t  j||||d || _d| _td ddd | _d | _d S )Nr   TF)r   r   	_proactor_unregister_proactorr\   CreateEvent_event
_event_fut)r   r   rM   rN   proactorr   r   r!   r"   r      s
   
z_WaitHandleFuture.__init__c                    sF   | j d urt| j  d | _ d | _| j| j d | _t | d S r>   )	rn   rP   CloseHandlero   rk   _unregisterr   r   rZ   rX   r   r!   r"   rZ      s   
	z%_WaitHandleFuture._unregister_wait_cbc              
   C   s   | j sd S d| _ | j}d | _z	t|| j W n3 tyJ } z'|jtjkr@d|| d}| jr3| j|d< | j	
| W Y d }~d S W Y d }~nd }~ww | j| j| j| _d S r[   )rL   rK   r\   UnregisterWaitExrn   r3   r^   r_   r   r4   r5   rk   _wait_cancelrZ   ro   r`   r!   r!   r"   ra      s.   


z"_WaitHandleFuture._unregister_wait)rD   rE   rF   r   rZ   ra   rH   r!   r!   r   r"   rj      s    rj   c                   @   s<   e Zd ZdZdd Zdd Zdd Zdd	 Zd
d ZeZ	dS )
PipeServerzXClass representing a pipe server.

    This is much like a bound, listening socket.
    c                 C   s,   || _ t | _d | _d | _| d| _d S NT)_addressweakrefWeakSet_free_instances_pipe_accept_pipe_future_server_pipe_handle)r   r)   r!   r!   r"   r      s
   
zPipeServer.__init__c                 C   s   | j | d}| _ |S )NF)r{   r}   )r   tmpr!   r!   r"   _get_unconnected_pipe  s   z PipeServer._get_unconnected_pipec              
   C   sr   |   rd S tjtjB }|r|tjO }t| j|tjtjB tj	B tj
tjtjtjtj}t|}| j| |S r>   )closedrP   PIPE_ACCESS_DUPLEXFILE_FLAG_OVERLAPPEDFILE_FLAG_FIRST_PIPE_INSTANCECreateNamedPiperw   PIPE_TYPE_MESSAGEPIPE_READMODE_MESSAGE	PIPE_WAITPIPE_UNLIMITED_INSTANCESr   BUFSIZENMPWAIT_WAIT_FOREVERNULL
PipeHandlerz   add)r   firstflagshpiper!   r!   r"   r}     s"   


zPipeServer._server_pipe_handlec                 C   s
   | j d u S r>   )rw   rS   r!   r!   r"   r        
zPipeServer.closedc                 C   sV   | j d ur| j   d | _ | jd ur)| jD ]}|  qd | _d | _| j  d S d S r>   )r|   r2   rw   rz   closer{   clear)r   r   r!   r!   r"   r   "  s   




zPipeServer.closeN)
rD   rE   rF   rG   r   r   r}   r   r   __del__r!   r!   r!   r"   ru      s    
ru   c                   @   s   e Zd ZdZdS )_WindowsSelectorEventLoopz'Windows version of selector event loop.N)rD   rE   rF   rG   r!   r!   r!   r"   r   1      r   c                       sJ   e Zd ZdZd fdd	Z fddZdd Zd	d
 Z	dddZ  Z	S )r   z2Windows version of proactor event loop using IOCP.Nc                    s   |d u rt  }t | d S r>   )r   r   r   )r   rp   r   r!   r"   r   8  s   zProactorEventLoop.__init__c              	      s   z2| j d u sJ | | j t   W | j d ur1| j j}| j   |d ur,| j| d | _ d S d S | j d urN| j j}| j   |d urK| j| d | _ w r>   )	_self_reading_future	call_soon_loop_self_readingr   run_foreverr   r2   rk   rr   r   r   r   r!   r"   r   =  s    



zProactorEventLoop.run_foreverc                    s:   | j |}|I d H }| }| j||d|id}||fS )Naddrextra)rk   connect_pipe_make_duplex_pipe_transport)r   protocol_factoryr)   fr   protocoltransr!   r!   r"   create_pipe_connectionP  s   
z(ProactorEventLoop.create_pipe_connectionc                    s0   t  d fdd	 gS )Nc              
      sT  d }z7| r'|   }j|  r|  W d S  }j||d id  }|d u r2W d S j|} W nf t	yT   |rL|
 dkrL|   Y d S  ty } z-|rq|
 dkrqd||d |  njr|tjd|dd  W Y d }~d S d }~w tjy   |r|  Y d S Y d S w | _|  d S )	Nr   r   r   zPipe accept failed)r.   r/   r   zAccept pipe failed on pipe %rT)exc_info)rC   rz   discardr   r   r   r   rk   accept_pipeBrokenPipeErrorfilenor   r3   r5   _debugr   warningr   CancelledErrorr|   add_done_callback)r   r   r   r6   r)   loop_accept_piper   r   serverr!   r"   r   [  sR   

z>ProactorEventLoop.start_serving_pipe.<locals>.loop_accept_piper>   )ru   r   )r   r   r)   r!   r   r"   start_serving_pipeX  s
   
-z$ProactorEventLoop.start_serving_pipec	              	      sx   |   }
t| |||||||f|
|d|	}z|
I d H  W |S  ttfy)     ty;   |  | I d H   w )N)waiterr   )create_future_WindowsSubprocessTransport
SystemExitKeyboardInterruptBaseExceptionr   _wait)r   r   argsshellstdinstdoutstderrbufsizer   kwargsr   transpr!   r!   r"   _make_subprocess_transport  s&   
z,ProactorEventLoop._make_subprocess_transportr>   )
rD   rE   rF   rG   r   r   r   r   r   rH   r!   r!   r   r"   r   5  s    5r   c                   @   s   e Zd ZdZd;ddZdd Zdd Zd	d
 Zd<ddZdd Z	d=ddZ
d=ddZd=ddZd>ddZd=ddZdd Zdd Zdd  Zd!d" Zd#d$ Zd<d%d&Zd'd( Zd)d* Zd+d, Zd-d. Zd/d0 Zd1d2 Zd<d3d4Zd5d6 Zd7d8 Zd9d: ZdS )?r   z#Proactor implementation using IOCP.r   c                 C   sD   d | _ g | _ttjtd|| _i | _t	 | _
g | _t	 | _d S rO   )r4   _resultsr\   CreateIoCompletionPortINVALID_HANDLE_VALUEr   _iocp_cacherx   ry   rL   _unregistered_stopped_serving)r   concurrencyr!   r!   r"   r     s   

zIocpProactor.__init__c                 C   s   | j d u r	tdd S )NzIocpProactor is closed)r   rg   rS   r!   r!   r"   _check_closed  s   
zIocpProactor._check_closedc                 C   sF   dt | j dt | j g}| jd u r|d d| jjd|f S )Nzoverlapped#=%sz
result#=%sr   z<%s %s> )lenr   r   r   rW   r    rD   join)r   r+   r!   r!   r"   __repr__  s   

zIocpProactor.__repr__c                 C   s
   || _ d S r>   )r4   )r   r   r!   r!   r"   set_loop  r   zIocpProactor.set_loopNc                 C   s.   | j s| | | j }g | _ z|W d }S d }w r>   )r   rT   )r   timeoutr~   r!   r!   r"   select  s   
zIocpProactor.selectc                 C   s   | j  }|| |S r>   )r4   r   rA   )r   valuerY   r!   r!   r"   _result     

zIocpProactor._resultr   c                 C   |   |  | tt}zt|tjr|| || n|| | W n t	y2   | 
d Y S w dd }| |||S )N    c              
   S   B   z|  W S  ty  } z|jtjtjfv rt|j  d }~ww r>   	getresultr3   r^   r\   ERROR_NETNAME_DELETEDERROR_OPERATION_ABORTEDConnectionResetErrorr   r   keyr   r6   r!   r!   r"   finish_recv     

z&IocpProactor.recv.<locals>.finish_recv)_register_with_iocpr\   
Overlappedr   
isinstancesocketWSARecvr   ReadFiler   r   	_registerr   connnbytesr   r   r   r!   r!   r"   recv     


zIocpProactor.recvc                 C   r   )Nr   c              
   S   r   r>   r   r   r!   r!   r"   r     r   z+IocpProactor.recv_into.<locals>.finish_recv)r   r\   r   r   r   r   WSARecvIntor   ReadFileIntor   r   r   )r   r   bufr   r   r   r!   r!   r"   	recv_into  r   zIocpProactor.recv_intoc                 C   s^   |  | tt}z|| || W n ty#   | d Y S w dd }| |||S )N)r   Nc              
   S   r   r>   r   r   r!   r!   r"   r      r   z*IocpProactor.recvfrom.<locals>.finish_recv)	r   r\   r   r   WSARecvFromr   r   r   r   r   r!   r!   r"   recvfrom  s   


zIocpProactor.recvfromc                 C   s>   |  | tt}|| ||| dd }| |||S )Nc              
   S   r   r>   r   r   r!   r!   r"   finish_send  r   z(IocpProactor.sendto.<locals>.finish_send)r   r\   r   r   	WSASendTor   r   )r   r   r   r   r   r   r   r!   r!   r"   sendto  s
   


zIocpProactor.sendtoc                 C   sZ   |  | tt}t|tjr|| || n|| | dd }| 	|||S )Nc              
   S   r   r>   r   r   r!   r!   r"   r   &  r   z&IocpProactor.send.<locals>.finish_send)
r   r\   r   r   r   r   WSASendr   	WriteFiler   )r   r   r   r   r   r   r!   r!   r"   send  s   


zIocpProactor.sendc                    sv   |   | j tt}|     fdd}dd }| ||}|| }t	j
|| jd |S )Nc                    sD   |   td } tjtj|  	
     fS )Nz@P)r   structpackr   
setsockoptr   
SOL_SOCKETr\   SO_UPDATE_ACCEPT_CONTEXT
settimeout
gettimeoutgetpeername)r   r   r   r   r   listenerr!   r"   finish_accept8  s   z*IocpProactor.accept.<locals>.finish_acceptc                    s.   z| I d H  W d S  t jy   |   w r>   )r   r   r   )r0   r   r!   r!   r"   accept_coroA  s   z(IocpProactor.accept.<locals>.accept_coror   )r   _get_accept_socketfamilyr\   r   r   AcceptExr   r   r
   ensure_futurer4   )r   r  r   r  r  r0   coror!   r  r"   accept2  s   

	
zIocpProactor.acceptc              
      s    j tjkrt  | | j }|d  |S | 	  zt
   j W n" tyL } z|jtjkr9   d dkrB W Y d }~nd }~ww tt}|  |  fdd}| | |S )Nr   r   c                    s   |    tjtjd  S rO   )r   r   r   r   r\   SO_UPDATE_CONNECT_CONTEXTr   r   r   r   r!   r"   finish_connectd  s
   z,IocpProactor.connect.<locals>.finish_connect)typer   
SOCK_DGRAMr\   
WSAConnectr   r4   r   rA   r   	BindLocalr  r3   r^   errno	WSAEINVALgetsocknamer   r   	ConnectExr   )r   r   r)   rY   er   r  r!   r  r"   connectN  s(   



zIocpProactor.connectc           	   	   C   sb   |  | tt}|d@ }|d? d@ }|| t| |||dd dd }| |||S )Nr       r   c              
   S   r   r>   r   r   r!   r!   r"   finish_sendfilew  r   z.IocpProactor.sendfile.<locals>.finish_sendfile)	r   r\   r   r   TransmitFiler   msvcrtget_osfhandler   )	r   sockfileoffsetcountr   
offset_lowoffset_highr  r!   r!   r"   sendfilem  s   


	zIocpProactor.sendfilec                    sJ   |    tt}|  }|r|  S  fdd}| | |S )Nc                    s   |    S r>   )r   r  r   r!   r"   finish_accept_pipe  s   z4IocpProactor.accept_pipe.<locals>.finish_accept_pipe)r   r\   r   r   ConnectNamedPiper   r   r   )r   r   r   	connectedr(  r!   r'  r"   r     s   


zIocpProactor.accept_pipec              
      st   t }	 zt|}W n) ty$ } z|jtjkr W Y d }~nd }~ww t|d t}t	|I d H  qt
|S )NT   )CONNECT_PIPE_INIT_DELAYr\   ConnectPiper3   r^   ERROR_PIPE_BUSYminCONNECT_PIPE_MAX_DELAYr
   sleepr   r   )r   r)   delayrM   r6   r!   r!   r"   r     s    

zIocpProactor.connect_pipec                 C   s   |  ||dS )zWait for a handle.

        Return a Future object. The result of the future is True if the wait
        completed, or False if the wait did not complete (on timeout).
        F)_wait_for_handle)r   rM   r   r!   r!   r"   wait_for_handle  s   zIocpProactor.wait_for_handlec                 C   s   |  |d d}||_|S rv   )r3  re   )r   rf   done_callbackrY   r!   r!   r"   rt     s   zIocpProactor._wait_cancelc                    s   |    |d u rtj}nt|d }tt}t|| j	|j
|}|r.t|||| jd n
t|||| | jd  jr? jd=  fdd} |d|f| j|j
<  S )N     @@r   r   c                    s      S r>   )rT   r  r   r!   r"   finish_wait_for_handle  s   z=IocpProactor._wait_for_handle.<locals>.finish_wait_for_handler   )r   rP   INFINITEmathceilr\   r   r   RegisterWaitWithQueuer   r)   rd   r4   rj   r   r   )r   rM   r   
_is_cancelmsr   rN   r8  r!   r7  r"   r3    s$   

	zIocpProactor._wait_for_handlec                 C   s4   || j vr| j | t| | jdd d S d S rO   )rL   r   r\   r   r   r   r   objr!   r!   r"   r     s   
z IocpProactor._register_with_iocpc              
   C   s   |    t|| jd}|jr|jd= |js:z|d d |}W n ty4 } z|| W Y d }~n
d }~ww || ||||f| j|j	< |S r   )
r   r   r4   r   r#   r3   r?   rA   r   r)   )r   r   r@  callbackr   r   r  r!   r!   r"   r     s   

zIocpProactor._registerc                 C   s   |    | j| dS )a  Unregister an overlapped object.

        Call this method when its future has been cancelled. The event can
        already be signalled (pending in the proactor event queue). It is also
        safe if the event is never signalled (because it was cancelled).
        N)r   r   rW   r   r!   r!   r"   rr     s   zIocpProactor._unregisterc                 C   s   t  |}|d |S rO   )r   r   )r   r  sr!   r!   r"   r    r   zIocpProactor._get_accept_socketc                 C   s  |d u rt }n|dk rtdt|d }|t krtd	 t| j|}|d u r+nd}|\}}}}z| j|\}}	}
}W n) t	yh   | j
 rZ| j
dd||||f d |dtjfvrft| Y qw |
| jv rs|  n=| sz5z||||	}W n ty } z|| | j| W Y d }~nd }~ww || | j| W d }nd }w q| jD ]
}	| j|	jd  q| j  d S )	Nr   znegative timeoutr6  ztimeout too bigTz8GetQueuedCompletionStatus() returned an unexpected eventz)err=%s transferred=%s key=%#x address=%#x)r.   status)r9  
ValueErrorr:  r;  r\   GetQueuedCompletionStatusr   r   popKeyErrorr4   	get_debugr5   r   rP   rq   r   r2   doner3   r?   r   rW   rA   r   r)   r   )r   r   r>  rC  errtransferredr   r)   r   r   r@  rA  r   r  r!   r!   r"   rT     sZ   

	





)zIocpProactor._pollc                 C   s   | j | d S r>   )r   r   r?  r!   r!   r"   _stop_servingI  s   zIocpProactor._stop_servingc                 C   s  | j d u rd S t| j D ]D\}\}}}}| rqt|tr!qz|  W q tyR } z| j	d urHd||d}|j
rB|j
|d< | j	| W Y d }~qd }~ww d}t }	|	| }
| jr|
t krwtd| t |	  t | }
| | | js`g | _t| j  d | _ d S )NzCancelling a future failedr-   r1   g      ?z,%r is running after closing for %.1f seconds)r   listr   items	cancelledr   rd   r2   r3   r4   r   r5   time	monotonicr   debugrT   r   rP   rq   )r   r)   rY   r   r@  rA  r6   r7   
msg_update
start_timenext_msgr!   r!   r"   r   O  sD   




	
zIocpProactor.closec                 C   s   |    d S r>   )r   rS   r!   r!   r"   r   ~  s   zIocpProactor.__del__)r   r>   )r   )r   N)rD   rE   rF   rG   r   r   r   r   r   r   r   r   r   r   r   r  r  r&  r   r   r4  rt   r3  r   r   rr   r  rT   rL  r   r   r!   r!   r!   r"   r     s:    








"
 

9/r   c                   @   s   e Zd Zdd ZdS )r   c           
         sP   t j|f|||||d| _ fdd} jjt jj}	|	| d S )N)r   r   r   r   r   c                    s    j  } | d S r>   )_procpoll_process_exited)r   
returncoderS   r!   r"   rA    s   
z4_WindowsSubprocessTransport._start.<locals>.callback)	r   PopenrV  r4   rk   r4  intrJ   r   )
r   r   r   r   r   r   r   r   rA  r   r!   rS   r"   _start  s   z"_WindowsSubprocessTransport._startN)rD   rE   rF   r\  r!   r!   r!   r"   r     s    r   c                   @      e Zd ZeZdS )r   N)rD   rE   rF   r   _loop_factoryr!   r!   r!   r"   r     r   r   c                   @   r]  )r   N)rD   rE   rF   r   r^  r!   r!   r!   r"   r     r   r   )2rG   sysplatformImportErrorr\   rP   r  r:  r  r   r   rP  rx    r   r   r   r   r   r	   r
   r   logr   __all__r   r9  ERROR_CONNECTION_REFUSEDERROR_CONNECTION_ABORTEDr,  r0  Futurer   rI   rd   rj   objectru   BaseSelectorEventLoopr   BaseProactorEventLoopr   r   BaseSubprocessTransportr   r   BaseDefaultEventLoopPolicyr   r   r   r!   r!   r!   r"   <module>   sZ    
0J4;j   f