3
ebN                 @   sh  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hZye W n ek
r   i ZY nX dd ZG dd deZeeefZdd	 Zd
d Z dd Z!dd Z"d&ddZ#d'ddZ$e$Z%d(ddZ&G dd dZ'G dd de'Z(dd Z)d)dd Z*ej+d!krdG d"d# d#Z,G d$d% d%e'Z-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   s>   y
t j| S  tttfk
r8   | tkr0t|  S d|  S X d S )NzUnknown error %s)osstrerror
ValueErrorOverflowError	NameErrorr   )err r   /usr/lib/python3.6/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   W n( tk
r"    Y n   | j  Y nX d S )N)handle_read_event_reraised_exceptionshandle_error)objr   r   r   readQ   s    r    c             C   s:   y| j   W n( tk
r"    Y n   | j  Y nX d S )N)handle_write_eventr   r   )r   r   r   r   writeY   s    r"   c             C   s:   y| j   W n( tk
r"    Y n   | j  Y nX d S )N)handle_expt_eventr   r   )r   r   r   r   
_exceptiona   s    r$   c             C   s   yX|t j@ r| j  |t j@ r&| j  |t j@ r8| j  |t jt jB t j	B @ rV| j
  W nh tk
r } z&|jd tkr| j  n| j
  W Y d d }~X n( tk
r    Y n   | j  Y nX d S )Nr   )selectPOLLINr   POLLOUTr!   POLLPRIr#   ZPOLLHUPZPOLLERRZPOLLNVALhandle_closeOSErrorargs_DISCONNECTEDr   r   )r   flagser   r   r   	readwritei   s"    



r/           c       	      C   sN  |d krt }|rJg }g }g }x^t|j D ]N\}}|j }|j }|rR|j| |rh|j rh|j| |sp|r,|j| q,W g |  ko|  ko|kn  rtj|  d S t	j	|||| \}}}x(|D ] }|j
|}|d krqt| qW x*|D ]"}|j
|}|d krqt| qW x.|D ]&}|j
|}|d kr<q t| q W d S )N)
socket_maplistitemsreadablewritableappend	acceptingtimeZsleepr%   getr    r"   r$   )	timeoutmaprwr.   fdr   Zis_rZis_wr   r   r   poll}   sD      

"








r?   c             C   s   |d krt }| d k	r t| d } tj }|rx^t|j D ]N\}}d}|j r^|tjtjB O }|j	 rx|j
 rx|tjO }|r:|j|| q:W |j| }x.|D ]&\}}|j|}|d krqt|| qW d S )Ni  r   )r1   intr%   r?   r2   r3   r4   r&   r(   r5   r7   r'   registerr9   r/   )r:   r;   Zpollsterr>   r   r-   r<   r   r   r   poll2   s(    


rB         >@Fc             C   sj   |d krt }|r ttdr t}nt}|d krBx8|r>|| | q.W n$x"|rd|dkrd|| | |d }qDW d S )Nr?   r      )r1   hasattrr%   rB   r?   )r:   Zuse_pollr;   countZpoll_funr   r   r   loop   s    
rG   c               @   s6  e Zd ZdZdZdZdZdZdZe	dhZ
dAddZdd ZeZdBdd	ZdCd
dZejejfddZdDd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dEd'd(Z d)d* Z!d+d, Z"d-d. Z#d/d0 Z$d1d2 Z%d3d4 Z&d5d6 Z'd7d8 Z(d9d: Z)d;d< Z*d=d> Z+d?d@ Z,dS )F
dispatcherFNwarningc             C   s   |d krt | _n|| _d | _|r|jd | j|| d| _y|j | _W q tk
r } z,|j	d t
tfkrvd| _n| j|  W Y d d }~X qX nd | _d S )Nr   TF)r1   _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r>|jd | jd k	ry|jd| j  W n$ tk
r   |jt| j Y nX ddj	|t
| f S )N.Z	listeningrN   z%s:%dz<%s at %#x> )	__class__r   r   r7   rO   r6   rN   	TypeErrorreprjoinid)rR   Zstatusr   r   r   __repr__   s    

zdispatcher.__repr__c             C   s   |d kr| j }| || j< d S )N)rJ   rK   )rR   r;   r   r   r   add_channel  s    zdispatcher.add_channelc             C   s,   | j }|d kr| j}||kr"||= d | _ d S )N)rK   rJ   )rR   r;   r>   r   r   r   rP     s    zdispatcher.del_channelc             C   s.   ||f| _ tj||}|jd | j| d S )Nr   )Zfamily_and_typerQ   rL   rM   )rR   ZfamilytyperS   r   r   r   create_socket  s    

zdispatcher.create_socketc             C   s   || _ |j | _| j| d S )N)rQ   filenorK   r]   )rR   rS   r;   r   r   r   rM      s    
zdispatcher.set_socketc             C   sD   y*| j jt jt j| j jt jt jdB  W n tk
r>   Y nX d S )NrD   )rQ   Z
setsockopt
SOL_SOCKETZSO_REUSEADDR
getsockoptr*   )rR   r   r   r   set_reuse_addr&  s    
zdispatcher.set_reuse_addrc             C   s   dS )NTr   )rR   r   r   r   r4   7  s    zdispatcher.readablec             C   s   dS )NTr   )rR   r   r   r   r5   :  s    zdispatcher.writablec             C   s(   d| _ tjdkr|dkrd}| jj|S )NTnt   )r7   r   namerQ   listen)rR   Znumr   r   r   rg   A  s    zdispatcher.listenc             C   s   || _ | jj|S )N)rO   rQ   bind)rR   rO   r   r   r   rh   G  s    zdispatcher.bindc             C   sp   d| _ d| _| jj|}|tttfks8|tkrBtj	dkrB|| _
d S |dtfkr^|| _
| j  nt|t| d S )NFTrd   r   )rN   
connectingrQ   Z
connect_exr   r   r   r   r   rf   rO   r	   handle_connect_eventr*   r   )rR   Zaddressr   r   r   r   connectK  s    
zdispatcher.connectc             C   sn   y| j j \}}W nN tk
r&   d S  tk
r` } z |jd tttfkrNd S  W Y d d }~X n
X ||fS d S )Nr   )rQ   acceptrX   r*   r+   r   r   r   )rR   ZconnrO   whyr   r   r   rl   Y  s    zdispatcher.acceptc             C   sf   y| j j|}|S  tk
r` } z4|jd tkr4dS |jd tkrN| j  dS  W Y d d }~X nX d S )Nr   )rQ   sendr*   r+   r   r,   r)   )rR   dataresultrm   r   r   r   rn   g  s    zdispatcher.sendc             C   sh   y$| j j|}|s| j  dS |S W n> tk
rb } z"|jd tkrP| j  dS  W Y d d }~X nX d S )N    r   )rQ   recvr)   r*   r+   r,   )rR   buffer_sizero   rm   r   r   r   rr   t  s    zdispatcher.recvc             C   sn   d| _ d| _d| _| j  | jd k	rjy| jj  W n6 tk
rh } z|jd tt	fkrX W Y d d }~X nX d S )NFr   )
rN   r7   ri   rP   rQ   closer*   r+   r   r
   )rR   rm   r   r   r   rt     s    
zdispatcher.closec             C   s   t jjdt|  d S )Nzlog: %s
)sysstderrr"   str)rR   messager   r   r   log  s    zdispatcher.loginfoc             C   s   || j krtd||f  d S )Nz%s: %s)ignore_log_typesprint)rR   rx   r^   r   r   r   log_info  s    
zdispatcher.log_infoc             C   s:   | j r| j  n&| js.| jr$| j  | j  n| j  d S )N)r7   handle_acceptrN   ri   rj   handle_read)rR   r   r   r   r     s    

zdispatcher.handle_read_eventc             C   s@   | j jt jt j}|dkr(t|t|| j  d| _d| _d S )Nr   TF)	rQ   rb   ra   SO_ERRORr*   r   handle_connectrN   ri   )rR   r   r   r   r   rj     s    zdispatcher.handle_connect_eventc             C   s*   | j r
d S | js| jr| j  | j  d S )N)r7   rN   ri   rj   handle_write)rR   r   r   r   r!     s    zdispatcher.handle_write_eventc             C   s0   | j jt jt j}|dkr$| j  n| j  d S )Nr   )rQ   rb   ra   r   r)   handle_expt)rR   r   r   r   r   r#     s    
zdispatcher.handle_expt_eventc             C   sX   t  \}}}}yt| }W n   dt|  }Y n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_tracebackrY   r[   r}   r)   )rR   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 eventrI   )r}   )rR   r   r   r   r     s    zdispatcher.handle_exptc             C   s   | j dd d S )Nzunhandled read eventrI   )r}   )rR   r   r   r   r     s    zdispatcher.handle_readc             C   s   | j dd d S )Nzunhandled write eventrI   )r}   )rR   r   r   r   r     s    zdispatcher.handle_writec             C   s   | j dd d S )Nzunhandled connect eventrI   )r}   )rR   r   r   r   r     s    zdispatcher.handle_connectc             C   s   | j  }|d k	r| j|  d S )N)rl   handle_accepted)rR   Zpairr   r   r   r~     s    zdispatcher.handle_acceptc             C   s   |j   | jdd d S )Nzunhandled accepted eventrI   )rt   r}   )rR   rS   rO   r   r   r   r     s    zdispatcher.handle_acceptedc             C   s   | j dd | j  d S )Nzunhandled close eventrI   )r}   rt   )rR   r   r   r   r)     s    zdispatcher.handle_close)NN)N)N)N)rz   )-r   r   r   debugrN   r7   ri   closingrO   	frozensetr{   rT   r\   __str__r]   rP   rQ   ZAF_INETZSOCK_STREAMr_   rM   rc   r4   r5   rg   rh   rk   rl   rn   rr   rt   ry   r}   r   rj   r!   r#   r   r   r   r   r   r~   r   r)   r   r   r   r   rH      sL   

 

	

rH   c               @   s6   e Zd Z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   )rH   rT   
out_buffer)rR   rS   r;   r   r   r   rT     s    zdispatcher_with_send.__init__c             C   s.   d}t j| | jd d }| j|d  | _d S )Nr   i   )rH   rn   r   )rR   Znum_sentr   r   r   initiate_send  s    z"dispatcher_with_send.initiate_sendc             C   s   | j   d S )N)r   )rR   r   r   r   r     s    z!dispatcher_with_send.handle_writec             C   s   | j  pt| jS )N)rN   lenr   )rR   r   r   r   r5     s    zdispatcher_with_send.writablec             C   s0   | j r| jdt|  | j| | _| j  d S )Nz
sending %s)r   r}   rY   r   r   )rR   ro   r   r   r   rn     s    zdispatcher_with_send.send)NN)r   r   r   rT   r   r   r5   rn   r   r   r   r   r     s
   
r   c              C   s   t j \} }}g }|stdx0|rN|j|jjj|jjjt|j	f |j
}q W ~|d \}}}djdd |D }|||f| ||fS )Nztraceback does not existrD   rV   c             S   s   g | ]}d | qS )z
[%s|%s|%s]r   ).0xr   r   r   
<listcomp>)  s    z%compact_traceback.<locals>.<listcomp>)ru   exc_infoAssertionErrorr6   tb_framef_codeco_filenameco_namerw   	tb_linenotb_nextrZ   )r   r   tbr   fileZfunctionlinerz   r   r   r   r     s    
r   c             C   s   | d krt } x~t| j D ]n}y|j  W q tk
rb } z|jd tkrLn|sR W Y d d }~X q tk
rv    Y q   |s Y qX qW | j  d S )Nr   )	r1   r2   valuesrt   r*   r+   r
   r   clear)r;   Z
ignore_allr   r   r   r   	close_all,  s     r   posixc               @   sN   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>   )rR   r>   r   r   r   rT   Q  s    zfile_wrapper.__init__c             C   s*   | j dkrtjd|  t| d | j  d S )Nr   zunclosed file %r)source)r>   warningswarnResourceWarningrt   )rR   r   r   r   __del__T  s    
zfile_wrapper.__del__c             G   s   t j| jf| S )N)r   r    r>   )rR   r+   r   r   r   rr   Z  s    zfile_wrapper.recvc             G   s   t j| jf| S )N)r   r"   r>   )rR   r+   r   r   r   rn   ]  s    zfile_wrapper.sendNc             C   s*   |t jkr|t jkr| rdS tdd S )Nr   z-Only asyncore specific behaviour implemented.)rQ   ra   r   NotImplementedError)rR   levelZoptnameZbuflenr   r   r   rb   `  s
    

zfile_wrapper.getsockoptc             C   s(   | j dk rd S | j }d| _ tj| d S )Nr   rD   r   )r>   r   rt   )rR   r>   r   r   r   rt   k  s
    
zfile_wrapper.closec             C   s   | j S )N)r>   )rR   r   r   r   r`   r  s    zfile_wrapper.fileno)N)r   r   r   rT   r   rr   rn   rb   r    r"   rt   r`   r   r   r   r   r   L  s   
r   c               @   s   e Zd ZdddZdd ZdS )file_dispatcherNc             C   sP   t j| d | d| _y|j }W n tk
r4   Y nX | j| tj|d d S )NTF)rH   rT   rN   r`   AttributeErrorset_filer   set_blocking)rR   r>   r;   r   r   r   rT   w  s    
zfile_dispatcher.__init__c             C   s"   t || _| jj | _| j  d S )N)r   rQ   r`   rK   r]   )rR   r>   r   r   r   r     s    
zfile_dispatcher.set_file)N)r   r   r   rT   r   r   r   r   r   r   u  s   
r   )r0   N)r0   N)rC   FNN)NF).__doc__r%   rQ   ru   r8   r   r   errnor   r   r   r   r   r   r   r	   r
   r   r   r   r   r   r,   r1   r   r   	Exceptionr   KeyboardInterrupt
SystemExitr   r    r"   r$   r/   r?   rB   Zpoll3rG   rH   r   r   r   rf   r   r   r   r   r   r   <module>/   sB   <


'

  -
)