
\[\Z                 @   s  d  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 d l m Z d d d d g Z d Z d Z d Z d Z Gd d   d e
 j  Z Gd d   d e
 j  Z Gd d   d e  Z Gd d   d e j  Z Gd d   d e j   Z! Gd d   d  Z" Gd d    d  e	 j#  Z$ e Z% Gd! d"   d" e j&  Z' e' Z( d S)#z.Selector and proactor event loops for Windows.    N   )events)base_subprocess)futures)proactor_events)selector_events)tasks)windows_utils)_overlapped)	coroutine)loggerSelectorEventLoopProactorEventLoopIocpProactorDefaultEventLoopPolicyl    i  i  c                   s   e  Z d  Z d Z d d   f d d  Z   f d d   Z d d	   Z   f d
 d   Z   f d d   Z   f d d   Z	   S)_OverlappedFuturezSubclass of Future which represents an overlapped operation.

    Cancelling it will immediately cancel the overlapped operation.
    loopNc               s6   t    j d |  |  j r) |  j d =n  | |  _ d  S)Nr   r   )super__init___source_traceback_ov)selfovr   )	__class__ ,/usr/lib/python3.4/asyncio/windows_events.pyr   '   s    	z_OverlappedFuture.__init__c                s]   t    j   } |  j d  k	 rY |  j j r0 d n d } | j d d | |  j j f  n  | S)NpendingZ	completedr   zoverlapped=<%s, %#x>)r   
_repr_infor   r   insertaddress)r   infostate)r   r   r   r   -   s
    #z_OverlappedFuture._repr_infoc             C   s   |  j  d  k r d  Sy |  j  j   Wni t k
 r } zI i d d 6| d 6|  d 6} |  j rm |  j | d <n  |  j j |  WYd  d  } ~ Xn Xd  |  _  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_overlapped4   s    
	#z$_OverlappedFuture._cancel_overlappedc                s   |  j    t   j   S)N)r-   r   r'   )r   )r   r   r   r'   D   s    
z_OverlappedFuture.cancelc                s   t    j |  |  j   d  S)N)r   set_exceptionr-   )r   r$   )r   r   r   r.   H   s    z_OverlappedFuture.set_exceptionc                s   t    j |  d  |  _ d  S)N)r   
set_resultr   )r   result)r   r   r   r/   L   s    z_OverlappedFuture.set_result)
__name__
__module____qualname____doc__r   r   r-   r'   r.   r/   r   r   )r   r   r   !   s   r   c                   s   e  Z d  Z d Z d d   f d d  Z d d   Z   f d d	   Z d
 d   Z   f d d   Z   f d d   Z	   f d d   Z
   S)_WaitHandleFuturez2Subclass of Future which represents a wait handle.r   Nc               sQ   t    j d |  |  j r) |  j d =n  | |  _ | |  _ | |  _ | |  _ d  S)Nr   r   r   )r   r   r   _iocpr   _handle_wait_handle)r   Ziocpr   handleZwait_handler   )r   r   r   r   T   s    				z_WaitHandleFuture.__init__c             C   s   t  j |  j d  t  j k S)Nr   )_winapiZWaitForSingleObjectr7   ZWAIT_OBJECT_0)r   r   r   r   _poll_   s    z_WaitHandleFuture._pollc                sk   t    j   } | j d d |  j  |  j rg |  j   rA d n d } | j d d | |  j f  n  | S)Nr   z
handle=%#xZsignaledZwaitingzwait_handle=<%s, %#x>)r   r   r   r7   r8   r;   )r   r!   r"   )r   r   r   r   d   s    	z_WaitHandleFuture._repr_infoc             C   s   |  j  d  k r d  Sy t j |  j   Wn~ t k
 r } z^ | j t j k r i d d 6| d 6|  d 6} |  j r |  j | d <n  |  j j |  n  WYd  d  } ~ Xn Xd  |  _  d  |  _	 d  |  _
 d  S)Nz$Failed to unregister the wait handler#   r$   r%   r&   )r8   r
   ZUnregisterWaitr(   winerrorZERROR_IO_PENDINGr   r)   r*   r6   r   )r   r+   r,   r   r   r   _unregister_waitm   s     
	&		z"_WaitHandleFuture._unregister_waitc                sN   t    j   } |  j d  k	 r@ t j |  j d d |  j j  n  |  j   | S)NTr   )r   r'   r   r
   ZPostQueuedCompletionStatusr6   r    r=   )r   r0   )r   r   r   r'      s    
z_WaitHandleFuture.cancelc                s   t    j |  |  j   d  S)N)r   r.   r=   )r   r$   )r   r   r   r.      s    z_WaitHandleFuture.set_exceptionc                s   t    j |  |  j   d  S)N)r   r/   r=   )r   r0   )r   r   r   r/      s    z_WaitHandleFuture.set_result)r1   r2   r3   r4   r   r;   r   r=   r'   r.   r/   r   r   )r   r   r5   Q   s   		r5   c               @   sL   e  Z d  Z 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 j   |  _ d  |  _ d  |  _ |  j 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  |  j d  } |  _  | S)NF)rC   rE   )r   tmpr   r   r   _get_unconnected_pipe   s    z PipeServer._get_unconnected_pipec          	   C   s   |  j  d  k r d  St j t j B} | r9 | t j O} n  t j |  j  | t j t j Bt j Bt j	 t
 j t
 j t j t j  } t
 j |  } |  j j |  | S)N)r?   r:   ZPIPE_ACCESS_DUPLEXZFILE_FLAG_OVERLAPPEDZFILE_FLAG_FIRST_PIPE_INSTANCEZCreateNamedPipeZPIPE_TYPE_MESSAGEZPIPE_READMODE_MESSAGEZ	PIPE_WAITZPIPE_UNLIMITED_INSTANCESr	   ZBUFSIZEZNMPWAIT_WAIT_FOREVERNULL
PipeHandlerB   add)r   firstflagshpiper   r   r   rE      s    	zPipeServer._server_pipe_handlec             C   s{   |  j  d  k	 r( |  j  j   d  |  _  n  |  j d  k	 rw x |  j D] } | j   qA Wd  |  _ d  |  _ |  j j   n  d  S)N)rD   r'   r?   rB   closerC   clear)r   rN   r   r   r   rO      s    		zPipeServer.closeN)	r1   r2   r3   r4   r   rG   rE   rO   __del__r   r   r   r   r>      s   
r>   c               @   s"   e  Z d  Z d Z d d   Z d S)_WindowsSelectorEventLoopz'Windows version of selector event loop.c             C   s
   t  j   S)N)r	   
socketpair)r   r   r   r   _socketpair   s    z%_WindowsSelectorEventLoop._socketpairN)r1   r2   r3   r4   rT   r   r   r   r   rR      s   rR   c                   sp   e  Z d  Z d Z d   f d d  Z d d   Z e d d    Z e d	 d
    Z e d d d   Z	   S)r   z2Windows version of proactor event loop using IOCP.Nc                s,   | d  k r t    } n  t   j |  d  S)N)r   r   r   )r   Zproactor)r   r   r   r      s    zProactorEventLoop.__init__c             C   s
   t  j   S)N)r	   rS   )r   r   r   r   rT      s    zProactorEventLoop._socketpairc             c   sO   |  j  j |  } | Dd  H} |   } |  j | | d i | d 6} | | f S)Nextraaddr)	_proactorconnect_pipe_make_duplex_pipe_transport)r   protocol_factoryr    frN   protocoltransr   r   r   create_pipe_connection   s    	z(ProactorEventLoop.create_pipe_connectionc                sA   t      d        f d d    j    g S)Nc                sU  d  } y} |  rT |  j    }  j j |     }  j | | d i   d 6n   j   } | d  k rp d  S j j |  }  Wn t k
 r} zn | r | j   d k r  j	 i d d 6| d 6| d 6 | j
   n"  j rt j d | d	 d
 n  WYd  d  } ~ Xn> t j k
 r:| r6| j
   n  Yn X|   _ |  j   d  S)NrU   rV   r   zPipe accept failedr#   r$   rN   zAccept pipe failed on pipe %rexc_infoTr   )r0   rB   discardrY   rG   rW   accept_piper(   filenor*   rO   Z_debugr   Zwarningr   CancelledErrorrD   add_done_callback)r[   rN   r\   r+   )r    loop_accept_piperZ   r   serverr   r   re      s6    				"	z>ProactorEventLoop.start_serving_pipe.<locals>.loop_accept_pipe)r>   Z	call_soon)r   rZ   r    r   )r    re   rZ   r   rf   r   start_serving_pipe   s    !z$ProactorEventLoop.start_serving_pipec	             k   s=   t  |  | | | | | | | d | |	 }
 |
 j   Dd  H|
 S)NrU   )_WindowsSubprocessTransportZ
_post_init)r   r\   argsshellstdinstdoutstderrbufsizerU   kwargsZtranspr   r   r   _make_subprocess_transport  s
    z,ProactorEventLoop._make_subprocess_transport)
r1   r2   r3   r4   r   rT   r   r^   rg   rp   r   r   )r   r   r      s   	&c               @   s  e  Z d  Z d Z d d d  Z d d   Z 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 d  Z d d   Z d d d d   Z d! d"   Z d	 d# d$  Z d% d&   Z d' d(   Z d) d*   Z d	 S)+r   z#Proactor implementation using IOCP.l    c             C   s[   d  |  _  g  |  _ t j t j t d |  |  _ i  |  _ t j	   |  _
 t j	   |  _ d  S)Nr   )r)   _resultsr
   CreateIoCompletionPortINVALID_HANDLE_VALUErH   r6   _cacher@   rA   _registered_stopped_serving)r   Zconcurrencyr   r   r   r     s    			zIocpProactor.__init__c             C   s)   d |  j  j t |  j  t |  j  f S)Nz<%s overlapped#=%s result#=%s>)r   r1   lenrt   rq   )r   r   r   r   __repr__#  s    zIocpProactor.__repr__c             C   s   | |  _  d  S)N)r)   )r   r   r   r   r   set_loop(  s    zIocpProactor.set_loopNc             C   s/   |  j  s |  j |  n  |  j  } g  |  _  | S)N)rq   r;   )r   timeoutrF   r   r   r   select+  s
    			zIocpProactor.selectr   c             C   s   |  j  |  t j t  } t | t j  rJ | j | j   | |  n | j | j   |  d d   } |  j	 | | |  S)Nc             S   sa   y | j    SWnL t k
 r\ } z, | j t j k rG t | j    n   WYd  d  } ~ Xn Xd  S)N)	getresultr(   r<   r
   ERROR_NETNAME_DELETEDConnectionResetErrorri   )r]   keyr   r+   r   r   r   finish_recv:  s    z&IocpProactor.recv.<locals>.finish_recv)
_register_with_iocpr
   
OverlappedrH   
isinstancesocketZWSARecvrb   ZReadFile	_register)r   connnbytesrL   r   r   r   r   r   recv2  s    	zIocpProactor.recvc             C   s   |  j  |  t j t  } t | t j  rJ | j | j   | |  n | j | j   |  d d   } |  j	 | | |  S)Nc             S   sa   y | j    SWnL t k
 r\ } z, | j t j k rG t | j    n   WYd  d  } ~ Xn Xd  S)N)r|   r(   r<   r
   r}   r~   ri   )r]   r   r   r+   r   r   r   finish_sendM  s    z&IocpProactor.send.<locals>.finish_send)
r   r
   r   rH   r   r   ZWSASendrb   Z	WriteFiler   )r   r   bufrL   r   r   r   r   r   sendE  s    	zIocpProactor.sendc                s   |  j    |  j  j    t j t  } | j  j     j       f d d   } t d d    } |  j	 |  |  } | |    } t
 j | d |  j | S)Nc                s^   | j    t j d  j    }   j t j t j |    j	  j
        j   f S)Nz@P)r|   structZpackrb   
setsockoptr   
SOL_SOCKETr
   ZSO_UPDATE_ACCEPT_CONTEXT
settimeoutZ
gettimeoutZgetpeername)r]   r   r   r   )r   listenerr   r   finish_accept^  s    
z*IocpProactor.accept.<locals>.finish_acceptc             s   s6   y |  Dd  HWn" t  j k
 r1 | j     Yn Xd  S)N)r   rc   rO   )r%   r   r   r   r   accept_corog  s
    
z(IocpProactor.accept.<locals>.accept_coror   )r   _get_accept_socketfamilyr
   r   rH   ZAcceptExrb   r   r   r   Zasyncr)   )r   r   r   r   r   r%   Zcoror   )r   r   r   acceptX  s    		zIocpProactor.acceptc                s   |  j     y t j   j     j  WnY t k
 r } z9 | j t j k rW   n    j	   d d k rs   n  WYd  d  } ~ Xn Xt j
 t  } | j   j   |    f d d   } |  j |   |  S)Nr   r   c                s'   | j      j t j t j d    S)Nr   )r|   r   r   r   r
   ZSO_UPDATE_CONNECT_CONTEXT)r]   r   r   )r   r   r   finish_connect  s    
z,IocpProactor.connect.<locals>.finish_connect)r   r
   Z	BindLocalrb   r   r(   r<   errnoZ	WSAEINVALZgetsocknamer   rH   Z	ConnectExr   )r   r   r    er   r   r   )r   r   connectu  s    zIocpProactor.connectc                sZ   |  j     t j t  } | j   j      f d d   } |  j |   | d d S)Nc                s   | j      S)N)r|   )r]   r   r   )rN   r   r   finish_accept_pipe  s    
z4IocpProactor.accept_pipe.<locals>.finish_accept_piperegisterF)r   r
   r   rH   ZConnectNamedPiperb   r   )r   rN   r   r   r   )rN   r   ra     s    zIocpProactor.accept_pipec             C   sM   t  j t  } | j | |  j | j  d d   } |  j | d  | d d S)Nc             S   sz   |  t  j k r6 t  j |   } t d | d  |    n@ |  d k ri t  j |   } t d | d  |    n t j |  Sd  S)Nr   )r
   ZERROR_SEM_TIMEOUTZFormatMessageConnectionRefusedErrorr(   r	   rI   )errr9   r   msgr   r   r   finish_connect_pipe  s    z6IocpProactor.connect_pipe.<locals>.finish_connect_pipewait_for_postT)r
   r   rH   ZWaitNamedPipeAndConnectr6   r    r   )r   r    r   r   r   r   r   rX     s    zIocpProactor.connect_pipec       	         s"  | d  k r t  j } n t j | d  } t j t  } t j | |  j | j	 |  } t
 |  j | | | d |  j     j r   j d =n    f d d   }   j   ry   j   } Wn2 t k
 r } z   j |  WYd  d  } ~ XqX  j |  n    | d | f |  j | j	 <  S)Ng     @@r   r   c                s
     j    S)N)r;   )r]   r   r   )r[   r   r   finish_wait_for_handle  s    z<IocpProactor.wait_for_handle.<locals>.finish_wait_for_handler   r   )r:   INFINITEmathceilr
   r   rH   ZRegisterWaitWithQueuer6   r    r5   r)   r   r;   r(   r.   r/   rt   )	r   r9   rz   msr   Zwhr   r0   r+   r   )r[   r   wait_for_handle  s$    !		 zIocpProactor.wait_for_handlec             C   sE   | |  j  k rA |  j  j |  t j | j   |  j d d  n  d  S)Nr   )ru   rJ   r
   rr   rb   r6   )r   objr   r   r   r     s    z IocpProactor._register_with_iocpFTc       	      C   s   t  | d |  j } | j r+ | j d =n  | j r | r y | d  d  |  } Wn2 t k
 r } z | j |  WYd  d  } ~ Xq X| j |  n d } | r | | | | f |  j | j <n  | S)Nr   r   Tr   )	r   r)   r   r   r(   r.   r/   rt   r    )	r   r   r   callbackr   r   r[   valuer   r   r   r   r     s    	 zIocpProactor._registerc             C   s    t  j  |  } | j d  | S)Nr   )r   r   )r   r   sr   r   r   r     s    zIocpProactor._get_accept_socketc             C   s  | d  k r t  } nI | d k  r0 t d   n. t j | d  } | t  k r^ t d   n  xt j |  j |  } | d  k r d  Sd } | \ } } } } y" |  j j |  \ } }	 }
 } Wnz t	 k
 r<|  j
 j   r|  j
 j i d d 6d | | | | f d 6 n  | d t j f k r5t j |  n  wa Yn X|
 |  j k rY| j   qa | j   sa y | | | |	  } WnB t k
 r} z" | j |  |  j j |  WYd  d  } ~ XqX| j |  |  j j |  qa qa d  S)	Nr   znegative timeoutg     @@ztimeout too bigz8GetQueuedCompletionStatus() returned an unexpected eventr#   z)err=%s transferred=%s key=%#x address=%#xstatus)r   
ValueErrorr   r   r
   ZGetQueuedCompletionStatusr6   rt   popKeyErrorr)   Z	get_debugr*   rs   r:   CloseHandlerv   r'   doner(   r.   rq   appendr/   )r   rz   r   r   r   Ztransferredr   r    r[   r   r   r   r   r   r   r   r   r;     sD    	"#zIocpProactor._pollc             C   s   |  j  j |  d  S)N)rv   rJ   )r   r   r   r   r   _stop_serving8  s    zIocpProactor._stop_servingc             C   sd  x t  |  j j    D] \ } \ } } } } | d  k rG |  j | =q | j   rm | j   rm |  j | =q y | j   Wq t k
 r } z[ |  j d  k	 r i d d 6| d 6| d 6} | j r | j | d <n  |  j j	 |  n  WYd  d  } ~ Xq Xq Wx, |  j r+|  j
 d  s t j d  q q Wg  |  _ |  j d  k	 r`t j |  j  d  |  _ n  d  S)NzCancelling a future failedr#   r$   r%   r&   r   z"taking long time to close proactor)listrt   itemsr   Z	cancelledr'   r(   r)   r   r*   r;   r   debugrq   r6   r:   r   )r   r    Zfutr   r   r   r+   r,   r   r   r   rO   >  s.    .
	*	zIocpProactor.closec             C   s   |  j    d  S)N)rO   )r   r   r   r   rQ   `  s    zIocpProactor.__del__)r1   r2   r3   r4   r   rx   ry   r{   r   r   r   r   ra   rX   r   r   r   r   r;   r   rO   rQ   r   r   r   r   r     s&   	$%2"c               @   s   e  Z d  Z d d   Z d S)rh   c       
         sw   t  j | d | d | d | d | d | |   _   f d d   }   j j j t   j j   }	 |	 j |  d  S)Nrj   rk   rl   rm   rn   c                s      j  j   }   j |  d  S)N)_procZpollZ_process_exited)r[   
returncode)r   r   r   r   k  s    z4_WindowsSubprocessTransport._start.<locals>.callback)	r	   Popenr   r)   rW   r   intr7   rd   )
r   ri   rj   rk   rl   rm   rn   ro   r   r[   r   )r   r   _startf  s    !z"_WindowsSubprocessTransport._startN)r1   r2   r3   r   r   r   r   r   rh   d  s   rh   c               @   s   e  Z d  Z e Z d S)_WindowsDefaultEventLoopPolicyN)r1   r2   r3   r   Z_loop_factoryr   r   r   r   r   v  s   r   ))r4   r:   r   r   r   r   r@    r   r   r   r   r   r   r	   r
   Z
coroutinesr   logr   __all__rH   r   ZERROR_CONNECTION_REFUSEDZERROR_CONNECTION_ABORTEDZFuturer   r5   objectr>   ZBaseSelectorEventLooprR   ZBaseProactorEventLoopr   r   ZBaseSubprocessTransportrh   r   ZBaseDefaultEventLoopPolicyr   r   r   r   r   r   <module>   sB   		0B8E N