
[[\R                 @   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 m	 Z	 m
 Z
 m Z m Z m Z m Z m Z m Z m Z m Z m Z m Z e e e e e e e f  Z y e Wn e k
 r i  Z Yn Xd d   Z Gd d   d e  Z e e e f Z d d	   Z d
 d   Z  d d   Z! d d   Z" d d d d  Z# d d d d  Z$ e$ Z% d d d d d d  Z& Gd d   d  Z' Gd d   d e'  Z( d d   Z) d d d d   Z* e j+ d! k rd d l, Z, Gd" d#   d#  Z- Gd$ d%   d% e'  Z. n  d S)&a  Basic infrastructure for asynchronous socket service clients and servers.

There are only two ways to have a program on a single processor do "more
than one thing at a time".  Multi-threaded programming is the simplest and
most popular way to do it, but there is another very different technique,
that lets you have nearly all the advantages of multi-threading, without
actually using multiple threads. it's really only practical if your program
is largely I/O bound. If your program is CPU bound, then pre-emptive
scheduled threads are probably what you really need. Network servers are
rarely CPU-bound, however.

If your operating system supports the select() system call in its I/O
library (and nearly all do), then you can use it to juggle multiple
communication channels at once; doing other work while your I/O is taking
place in the "background."  Although this strategy can seem strange and
complex, especially at first, it is in many ways easier to understand and
control than multi-threaded programming. The module documented here solves
many of the difficult problems for you, making the task of building
sophisticated high-performance network servers and clients a snap.
    N)EALREADYEINPROGRESSEWOULDBLOCK
ECONNRESETEINVALENOTCONN	ESHUTDOWNEISCONNEBADFECONNABORTEDEPIPEEAGAIN	errorcodec             C   sO   y t  j |   SWn7 t t t f k
 rJ |  t k r> t |  Sd |  SYn Xd  S)NzUnknown error %s)osstrerror
ValueErrorOverflowError	NameErrorr   )err r   /usr/lib/python3.4/asyncore.py	_strerrorD   s    r   c               @   s   e  Z d  Z d S)ExitNowN)__name__
__module____qualname__r   r   r   r   r   L   s   r   c             C   s;   y |  j    Wn& t k
 r%   Yn |  j   Yn Xd  S)N)handle_read_event_reraised_exceptionshandle_error)objr   r   r   readQ   s    r    c             C   s;   y |  j    Wn& t k
 r%   Yn |  j   Yn Xd  S)N)handle_write_eventr   r   )r   r   r   r   writeY   s    r"   c             C   s;   y |  j    Wn& t k
 r%   Yn |  j   Yn Xd  S)N)handle_expt_eventr   r   )r   r   r   r   
_exceptiona   s    r$   c             C   s   yz | t  j @r |  j   n  | t  j @r7 |  j   n  | t  j @rQ |  j   n  | t  j t  j Bt  j	 B@ry |  j
   n  Wnt t k
 r } z/ | j d t k r |  j   n
 |  j
   WYd  d  } ~ Xn& t k
 r   Yn |  j   Yn Xd  S)Nr   )selectPOLLINr   POLLOUTr!   POLLPRIr#   ZPOLLHUPZPOLLERRZPOLLNVALhandle_closeOSErrorargs_DISCONNECTEDr   r   )r   flagser   r   r   	readwritei   s"    r/   g        c       	      C   s  | d  k r t  } n  | rg  } g  } g  } x t | j    D]v \ } } | j   } | j   } | rz | j |  n  | r | j r | j |  n  | s | r@ | j |  q@ q@ Wg  | k o | k o | k n r t j |   d  Sy% t	 j	 | | | |   \ } } } Wn t
 k
 r/d  SYn Xx9 | D]1 } | j |  } | d  k r^q7n  t |  q7Wx9 | D]1 } | j |  } | d  k rqsn  t |  qsWx< | D]1 } | j |  } | d  k rqn  t |  qWn  d  S)N)
socket_maplistitemsreadablewritableappend	acceptingtimeZsleepr%   InterruptedErrorgetr    r"   r$   )	timeoutmaprwr.   fdr   Zis_rZis_wr   r   r   poll}   sJ    	  '%	r?   c             C   sK  | d  k r t  } n  |  d  k	 r4 t |  d  }  n  t j   } | rGx t | j    D]t \ } } d } | j   r | t j t j BO} n  | j	   r | j
 r | t j O} n  | rY | j | |  qY qY Wy | j |   } Wn t k
 r g  } Yn XxE | D]: \ } } | j |  } | d  k r3qn  t | |  qWn  d  S)Ni  r   )r0   intr%   r?   r1   r2   r3   r&   r(   r4   r6   r'   registerr8   r9   r/   )r:   r;   Zpollsterr>   r   r-   r<   r   r   r   poll2   s.    	rB   g      >@Fc             C   s   | d  k r t  } n  | r3 t t d  r3 t } n t } | d  k rb xJ | r^ | |  |  qH Wn0 x- | r | d k r | |  |  | d } qe Wd  S)Nr?   r      )r0   hasattrr%   rB   r?   )r:   Zuse_pollr;   countZpoll_funr   r   r   loop   s    			rF   c               @   s  e  Z d  Z d Z d Z d Z d Z d Z d Z e	 d g  Z
 d d d d  Z d d   Z e Z d d d	  Z d d
 d  Z e j e j d d  Z d d d  Z d d   Z d d   Z d d   Z d d   Z d d   Z d d   Z 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/ d0   Z$ d1 d2   Z% d3 d4   Z& d5 d6   Z' d7 d8   Z( d9 d:   Z) d; d<   Z* d= d>   Z+ d? d@   Z, dA dB   Z- d S)C
dispatcherFNwarningc             C   s   | d  k r t  |  _ n	 | |  _ d  |  _ | r | j d  |  j | |  d |  _ y | j   |  _ Wq t k
 r } z: | j	 d t
 t f k r d |  _ n |  j |    WYd  d  } ~ Xq Xn	 d  |  _ d  S)Nr   TF)r0   _map_filenosetblocking
set_socket	connectedZgetpeernameaddrr*   r+   r   r   del_channelsocket)selfsockr;   r   r   r   r   __init__   s     			zdispatcher.__init__c             C   s   |  j  j d |  j  j g } |  j r? |  j r? | j d  n |  j rX | j d  n  |  j d  k	 r y | j d |  j  Wq t k
 r | j t |  j   Yq Xn  d d j	 |  t
 |   f S)N.Z	listeningrM   z%s:%dz<%s at %#x> )	__class__r   r   r6   rN   r5   rM   	TypeErrorreprjoinid)rQ   Zstatusr   r   r   __repr__  s    	zdispatcher.__repr__c             C   s)   | d  k r |  j  } n  |  | |  j <d  S)N)rI   rJ   )rQ   r;   r   r   r   add_channel  s    zdispatcher.add_channelc             C   sD   |  j  } | d  k r! |  j } n  | | k r7 | | =n  d  |  _  d  S)N)rJ   rI   )rQ   r;   r>   r   r   r   rO     s    	
zdispatcher.del_channelc             C   s?   | | f |  _  t j | |  } | j d  |  j |  d  S)Nr   )Zfamily_and_typerP   rK   rL   )rQ   ZfamilytyperR   r   r   r   create_socket  s    zdispatcher.create_socketc             C   s)   | |  _  | j   |  _ |  j |  d  S)N)rP   filenorJ   r\   )rQ   rR   r;   r   r   r   rL   %  s    	zdispatcher.set_socketc             C   sR   y9 |  j  j t  j t  j |  j  j t  j t  j  d B Wn t k
 rM Yn Xd  S)NrC   )rP   Z
setsockopt
SOL_SOCKETZSO_REUSEADDR
getsockoptr*   )rQ   r   r   r   set_reuse_addr+  s    	zdispatcher.set_reuse_addrc             C   s   d S)NTr   )rQ   r   r   r   r3   <  s    zdispatcher.readablec             C   s   d S)NTr   )rQ   r   r   r   r4   ?  s    zdispatcher.writablec             C   s=   d |  _  t j d k r- | d k r- d } n  |  j j |  S)NTnt   )r6   r   namerP   listen)rQ   Znumr   r   r   rf   F  s    		zdispatcher.listenc             C   s   | |  _  |  j j |  S)N)rN   rP   bind)rQ   rN   r   r   r   rg   L  s    	zdispatcher.bindc             C   s   d |  _  d |  _ |  j j |  } | t t t f k sT | t k ra t j	 d k ra | |  _
 d  S| d t f k r | |  _
 |  j   n t | t |   d  S)NFTrc   cer   )zntrh   )rM   
connectingrP   Z
connect_exr   r   r   r   r   re   rN   r	   handle_connect_eventr*   r   )rQ   Zaddressr   r   r   r   connectP  s    				zdispatcher.connectc             C   s   y |  j  j   \ } } Wn] t k
 r1 d  SYnR t k
 rx } z( | j d t t t f k rc d  S  WYd  d  } ~ Xn X| | f Sd  S)Nr   )rP   acceptrW   r*   r+   r   r   r   )rQ   ZconnrN   whyr   r   r   rl   ^  s    zdispatcher.acceptc             C   s   y |  j  j |  } | SWn` t k
 r| } z@ | j d t k rF d S| j d t k rg |  j   d S  WYd  d  } ~ Xn Xd  S)Nr   )rP   sendr*   r+   r   r,   r)   )rQ   dataresultrm   r   r   r   rn   l  s    
zdispatcher.sendc             C   s~   y. |  j  j |  } | s) |  j   d S| SWnI t k
 ry } z) | j d t k rd |  j   d S  WYd  d  } ~ Xn Xd  S)N    r   )rP   recvr)   r*   r+   r,   )rQ   Zbuffer_sizero   rm   r   r   r   rr   y  s    

zdispatcher.recvc             C   s   d |  _  d |  _ d |  _ |  j   |  j d  k	 r y |  j j   Wq t k
 r } z$ | j d t t	 f k ry   n  WYd  d  } ~ Xq Xn  d  S)NFr   )
rM   r6   ri   rO   rP   closer*   r+   r   r
   )rQ   rm   r   r   r   rs     s    			
zdispatcher.closec             C   s   y t  |  j |  } Wn. t k
 rF t d |  j j | f   Yn9 Xd i |  j j d 6| d 6} t j | t d d | Sd  S)Nz!%s instance has no attribute '%s'zA%(me)s.%(attr)s is deprecated; use %(me)s.socket.%(attr)s insteadmeattr
stacklevel   )getattrrP   AttributeErrorrV   r   warningswarnDeprecationWarning)rQ   ru   Zretattrmsgr   r   r   __getattr__  s    zdispatcher.__getattr__c             C   s   t  j j d t |   d  S)Nzlog: %s
)sysstderrr"   str)rQ   messager   r   r   log  s    zdispatcher.loginfoc             C   s*   | |  j  k r& t d | | f  n  d  S)Nz%s: %s)ignore_log_typesprint)rQ   r   r]   r   r   r   log_info  s    zdispatcher.log_infoc             C   sP   |  j  r |  j   n6 |  j sB |  j r5 |  j   n  |  j   n
 |  j   d  S)N)r6   handle_acceptrM   ri   rj   handle_read)rQ   r   r   r   r     s    			zdispatcher.handle_read_eventc             C   s_   |  j  j t  j t  j  } | d k r? t | t |    n  |  j   d |  _ d |  _ d  S)Nr   TF)	rP   ra   r`   SO_ERRORr*   r   handle_connectrM   ri   )rQ   r   r   r   r   rj     s    
	zdispatcher.handle_connect_eventc             C   s=   |  j  r d  S|  j s/ |  j r/ |  j   q/ n  |  j   d  S)N)r6   rM   ri   rj   handle_write)rQ   r   r   r   r!     s    			zdispatcher.handle_write_eventc             C   sB   |  j  j t  j t  j  } | d k r4 |  j   n
 |  j   d  S)Nr   )rP   ra   r`   r   r)   handle_expt)rQ   r   r   r   r   r#     s    zdispatcher.handle_expt_eventc             C   sn   t    \ } } } } y t |   } Wn d t |   } Yn X|  j d | | | | f d  |  j   d  S)Nz)<__repr__(self) failed for object at %0x>z:uncaptured python exception, closing channel %s (%s:%s %s)error)compact_tracebackrX   rZ   r   r)   )rQ   ZniltvtbinfoZ	self_reprr   r   r   r     s    zdispatcher.handle_errorc             C   s   |  j  d d  d  S)Nz!unhandled incoming priority eventrH   )r   )rQ   r   r   r   r     s    zdispatcher.handle_exptc             C   s   |  j  d d  d  S)Nzunhandled read eventrH   )r   )rQ   r   r   r   r     s    zdispatcher.handle_readc             C   s   |  j  d d  d  S)Nzunhandled write eventrH   )r   )rQ   r   r   r   r     s    zdispatcher.handle_writec             C   s   |  j  d d  d  S)Nzunhandled connect eventrH   )r   )rQ   r   r   r   r     s    zdispatcher.handle_connectc             C   s,   |  j    } | d  k	 r( |  j |   n  d  S)N)rl   handle_accepted)rQ   Zpairr   r   r   r     s    zdispatcher.handle_acceptc             C   s   | j    |  j d d  d  S)Nzunhandled accepted eventrH   )rs   r   )rQ   rR   rN   r   r   r   r     s    
zdispatcher.handle_acceptedc             C   s   |  j  d d  |  j   d  S)Nzunhandled close eventrH   )r   rs   )rQ   r   r   r   r)     s    zdispatcher.handle_close).r   r   r   debugrM   r6   ri   closingrN   	frozensetr   rS   r[   __str__r\   rO   rP   ZAF_INETZSOCK_STREAMr^   rL   rb   r3   r4   rf   rg   rk   rl   rn   rr   rs   r~   r   r   r   rj   r!   r#   r   r   r   r   r   r   r   r)   r   r   r   r   rG      sN    	rG   c               @   sR   e  Z d  Z d d d d  Z d d   Z d d   Z d d	   Z d
 d   Z d S)dispatcher_with_sendNc             C   s    t  j |  | |  d |  _ d  S)Nrq   )rG   rS   
out_buffer)rQ   rR   r;   r   r   r   rS     s    zdispatcher_with_send.__init__c             C   s?   d } t  j |  |  j d  d   } |  j | d   |  _ d  S)Nr   i   )rG   rn   r   )rQ   Znum_sentr   r   r   initiate_send  s    z"dispatcher_with_send.initiate_sendc             C   s   |  j    d  S)N)r   )rQ   r   r   r   r     s    z!dispatcher_with_send.handle_writec             C   s   |  j  p t |  j  S)N)rM   lenr   )rQ   r   r   r   r4     s    zdispatcher_with_send.writablec             C   sA   |  j  r# |  j d t |   n  |  j | |  _ |  j   d  S)Nz
sending %s)r   r   rX   r   r   )rQ   ro   r   r   r   rn   !  s    	zdispatcher_with_send.send)r   r   r   rS   r   r   r4   rn   r   r   r   r   r     s
   r   c              C   s   t  j   \ }  } } g  } | s0 t d   n  xD | rv | j | j j j | j j j t | j	  f  | j
 } q3 W~ | d \ } } } d j d d   | D  } | | | f |  | | f S)Nztraceback does not existrC   rU   c             S   s   g  |  ] } d  |  q S)z
[%s|%s|%s]r   ).0xr   r   r   
<listcomp><  s   	 z%compact_traceback.<locals>.<listcomp>)r   exc_infoAssertionErrorr5   tb_framef_codeco_filenameco_namer   	tb_linenotb_nextrY   )r   r   tbr   fileZfunctionliner   r   r   r   r   +  s    	r   c             C   s   |  d  k r t  }  n  x t |  j    D] } y | j   Wq( t k
 r } z' | j d t k rg n | ss   n  WYd  d  } ~ Xq( t k
 r   Yq( | s   n  Yq( Xq( W|  j   d  S)Nr   )	r0   r1   valuesrs   r*   r+   r
   r   clear)r;   Z
ignore_allr   r   r   r   	close_all?  s     	r   posixc               @   ss   e  Z d  Z d d   Z d d   Z d d   Z d d   Z d	 d
 d  Z e Z e Z	 d d   Z
 d d   Z d	 S)file_wrapperc             C   s   t  j |  |  _ d  S)N)r   dupr>   )rQ   r>   r   r   r   rS   f  s    zfile_wrapper.__init__c             C   s4   |  j  d k r& t j d |  t  n  |  j   d  S)Nr   zunclosed file %r)r>   rz   r{   ResourceWarningrs   )rQ   r   r   r   __del__i  s    zfile_wrapper.__del__c             G   s   t  j |  j |  S)N)r   r    r>   )rQ   r+   r   r   r   rr   n  s    zfile_wrapper.recvc             G   s   t  j |  j |  S)N)r   r"   r>   )rQ   r+   r   r   r   rn   q  s    zfile_wrapper.sendNc             C   s9   | t  j k r) | t  j k r) | r) d St d   d  S)Nr   z-Only asyncore specific behaviour implemented.)rP   r`   r   NotImplementedError)rQ   levelZoptnameZbuflenr   r   r   ra   t  s
    zfile_wrapper.getsockoptc             C   s0   |  j  d k  r d  St j |  j   d |  _  d  S)Nr   rC   r   )r>   r   rs   )rQ   r   r   r   rs     s    zfile_wrapper.closec             C   s   |  j  S)N)r>   )rQ   r   r   r   r_     s    zfile_wrapper.fileno)r   r   r   rS   r   rr   rn   ra   r    r"   rs   r_   r   r   r   r   r   a  s   r   c               @   s+   e  Z d  Z d d d  Z d d   Z d S)file_dispatcherNc             C   s   t  j |  d  |  d |  _ y | j   } Wn t k
 r@ Yn X|  j |  t j | t j d  } | t j	 B} t j | t j
 |  d  S)NTr   )rG   rS   rM   r_   ry   set_filefcntlZF_GETFLr   
O_NONBLOCKZF_SETFL)rQ   r>   r;   r-   r   r   r   rS     s    	zfile_dispatcher.__init__c             C   s/   t  |  |  _ |  j j   |  _ |  j   d  S)N)r   rP   r_   rJ   r\   )rQ   r>   r   r   r   r     s    zfile_dispatcher.set_file)r   r   r   rS   r   r   r   r   r   r     s   r   )/__doc__r%   rP   r   r7   rz   r   errnor   r   r   r   r   r   r   r	   r
   r   r   r   r   r   r,   r0   r   r   	Exceptionr   KeyboardInterrupt
SystemExitr   r    r"   r$   r/   r?   rB   Zpoll3rF   rG   r   r   r   re   r   r   r   r   r   r   r   <module>/   sB   X* :'