U
    çÑÙg~N  ã                   @   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z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   sH   zt  | ¡W S  tttfk
rB   | tkr6t|   Y S d|   Y S X d S )NzUnknown error %s)ÚosÚstrerrorÚ
ValueErrorÚOverflowErrorÚ	NameErrorr   )Úerr© r   ú/usr/lib/python3.8/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:   z|   ¡  W n( tk
r"   ‚ Y n   |  ¡  Y nX d S ©N)Úhandle_read_eventÚ_reraised_exceptionsÚhandle_error©Úobjr   r   r   ÚreadQ   s    r"   c                 C   s:   z|   ¡  W n( tk
r"   ‚ Y n   |  ¡  Y nX d S r   )Úhandle_write_eventr   r   r    r   r   r   ÚwriteY   s    r$   c                 C   s:   z|   ¡  W n( tk
r"   ‚ Y n   |  ¡  Y nX d S r   )Úhandle_expt_eventr   r   r    r   r   r   Ú
_exceptiona   s    r&   c              
   C   sÆ   zX|t j@ r|  ¡  |t j@ r&|  ¡  |t j@ r8|  ¡  |t jt jB t j	B @ rV|  
¡  W nh tk
rš } z$|jd tkr‚|  ¡  n|  
¡  W 5 d }~X Y n( tk
r®   ‚ Y n   |  ¡  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"    



r2   ç        c           	      C   s<  |d krt }|r8g }g }g }t| ¡ ƒD ]L\}}| ¡ }| ¡ }|rP| |¡ |rd|jsd| |¡ |sl|r*| |¡ q*g |  kr–|  kr–|kr¨n nt | ¡ d S t	 	|||| ¡\}}}|D ] }| 
|¡}|d krÚqÂt|ƒ qÂ|D ]"}| 
|¡}|d krqèt|ƒ qè|D ]&}| 
|¡}|d kr,qt|ƒ qd S r   )Ú
socket_mapÚlistÚitemsÚreadableÚwritableÚappendÚ	acceptingÚtimeÚsleepr(   Úgetr"   r$   r&   )	ÚtimeoutÚmapÚrÚwr1   Úfdr!   Zis_rZis_wr   r   r   Úpoll}   sD      


"







rC   c                 C   sÀ   |d krt }| d k	r t| d ƒ} t ¡ }|r¼t| ¡ ƒD ]L\}}d}| ¡ r\|tjtjB O }| 	¡ rt|j
st|tjO }|r8| ||¡ q8| | ¡}|D ]&\}}| |¡}|d kr°q”t||ƒ q”d S )Niè  r   )r4   Úintr(   rC   r5   r6   r7   r)   r+   r8   r:   r*   Úregisterr=   r2   )r>   r?   ZpollsterrB   r!   r0   r@   r   r   r   Úpoll2¤   s(    


rF   ç      >@Fc                 C   sb   |d krt }|r ttdƒr t}nt}|d kr>|r^|| |ƒ q,n |r^|dkr^|| |ƒ |d }q>d S )NrC   r   é   )r4   Úhasattrr(   rF   rC   )r>   Zuse_pollr?   ÚcountZpoll_funr   r   r   ÚloopÀ   s    
rK   c                   @   s2  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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–| d¡ |  ||¡ d| _z| ¡ | _W qœ tk
r’ } z*|j	d t
tfkrvd| _n|  |¡ ‚ W 5 d }~X Y qœX nd | _d S ©Nr   TF)r4   Ú_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.| d¡ n| jr>| d¡ | jd k	r‚z| d| j ¡ W n$ tk
r€   | t| jƒ¡ Y nX dd 	|¡t
| ƒf S )NÚ.Z	listeningrS   z%s:%dz<%s at %#x>ú )Ú	__class__r   r   r:   rT   r9   rS   Ú	TypeErrorÚreprÚjoinÚid)rW   Zstatusr   r   r   Ú__repr__ü   s    

zdispatcher.__repr__c                 C   s   |d kr| j }| || j< d S r   )rO   rP   )rW   r?   r   r   r   Úadd_channel	  s    zdispatcher.add_channelc                 C   s,   | j }|d kr| j}||kr"||= d | _ d S r   )rP   rO   )rW   r?   rB   r   r   r   rU     s    zdispatcher.del_channelc                 C   s.   ||f| _ t ||¡}| d¡ |  |¡ d S r'   )Zfamily_and_typerV   rQ   rR   )rW   ZfamilyÚtyperX   r   r   r   Úcreate_socket  s    

zdispatcher.create_socketc                 C   s   || _ | ¡ | _|  |¡ d S r   )rV   ÚfilenorP   rb   ©rW   rX   r?   r   r   r   rR     s    
zdispatcher.set_socketc                 C   sD   z*| j  t jt j| j  t jt j¡dB ¡ W n tk
r>   Y nX d S )NrH   )rV   Z
setsockoptÚ
SOL_SOCKETZSO_REUSEADDRÚ
getsockoptr-   ©rW   r   r   r   Úset_reuse_addr#  s     
ÿÿþzdispatcher.set_reuse_addrc                 C   s   dS ©NTr   ri   r   r   r   r7   4  s    zdispatcher.readablec                 C   s   dS rk   r   ri   r   r   r   r8   7  s    zdispatcher.writablec                 C   s(   d| _ tjdkr|dkrd}| j |¡S )NTÚnté   )r:   r   ÚnamerV   Úlisten)rW   Znumr   r   r   ro   >  s    zdispatcher.listenc                 C   s   || _ | j |¡S r   )rT   rV   Úbind)rW   rT   r   r   r   rp   D  s    zdispatcher.bindc                 C   sp   d| _ d| _| j |¡}|tttfks8|tkrBtj	dkrB|| _
d S |dtfkr^|| _
|  ¡  nt|t| ƒ‚d S )NFTrl   r   )rS   Ú
connectingrV   Z
connect_exr   r   r   r   r   rn   rT   r	   Úhandle_connect_eventr-   r   )rW   Zaddressr   r   r   r   ÚconnectH  s    ÿÿ
zdispatcher.connectc              
   C   sv   z| j  ¡ \}}W nV tk
r(   Y d S  tk
rh } z$|jd tttfkrVW Y ¢
d S ‚ W 5 d }~X Y n
X ||fS d S r'   )rV   Úacceptr]   r-   r.   r   r   r   )rW   ZconnrT   Úwhyr   r   r   rt   V  s    
zdispatcher.acceptc              
   C   st   z| j  |¡}|W S  tk
rn } z>|jd tkr<W Y ¢*dS |jd tkr\|  ¡  W Y ¢
dS ‚ W 5 d }~X Y nX d S r'   )rV   Úsendr-   r.   r   r/   r,   )rW   ÚdataÚresultru   r   r   r   rv   d  s    

zdispatcher.sendc              
   C   sr   z(| j  |¡}|s |  ¡  W dS |W S W nD tk
rl } z&|jd tkrZ|  ¡  W Y ¢
dS ‚ W 5 d }~X Y nX d S )Nó    r   )rV   Úrecvr,   r-   r.   r/   )rW   Zbuffer_sizerw   ru   r   r   r   rz   q  s    

zdispatcher.recvc              
   C   sn   d| _ d| _d| _|  ¡  | jd k	rjz| j ¡  W n6 tk
rh } z|jd tt	fkrX‚ W 5 d }~X Y nX d S )NFr   )
rS   r:   rq   rU   rV   Úcloser-   r.   r   r
   )rW   ru   r   r   r   r{   ƒ  s    
zdispatcher.closec                 C   s   t j dt|ƒ ¡ d S )Nzlog: %s
)ÚsysÚstderrr$   Ústr)rW   Ú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)rW   r   rc   r   r   r   Úlog_info–  s    
zdispatcher.log_infoc                 C   s:   | j r|  ¡  n&| js.| jr$|  ¡  |  ¡  n|  ¡  d S r   )r:   Úhandle_acceptrS   rq   rr   Úhandle_readri   r   r   r   r   š  s    

zdispatcher.handle_read_eventc                 C   s@   | j  t jt j¡}|dkr(t|t|ƒƒ‚|  ¡  d| _d| _d S rN   )	rV   rh   rg   ÚSO_ERRORr-   r   Úhandle_connectrS   rq   ©rW   r   r   r   r   rr   ¦  s    zdispatcher.handle_connect_eventc                 C   s*   | j r
d S | js| jr|  ¡  |  ¡  d S r   )r:   rS   rq   rr   Úhandle_writeri   r   r   r   r#   ®  s    zdispatcher.handle_write_eventc                 C   s0   | j  t jt j¡}|dkr$|  ¡  n|  ¡  d S r'   )rV   rh   rg   r‡   r,   Úhandle_exptr‰   r   r   r   r%   ¹  s    
zdispatcher.handle_expt_eventc                 C   sX   t ƒ \}}}}zt| ƒ}W n   dt| ƒ }Y nX |  d||||f d¡ |  ¡  d S )Nz)<__repr__(self) failed for object at %0x>z:uncaptured python exception, closing channel %s (%s:%s %s)Úerror)Úcompact_tracebackr^   r`   r„   r,   )rW   ZnilÚtÚvÚtbinfoZ	self_reprr   r   r   r   È  s    üù	zdispatcher.handle_errorc                 C   s   |   dd¡ d S )Nz!unhandled incoming priority eventrM   ©r„   ri   r   r   r   r‹   Ü  s    zdispatcher.handle_exptc                 C   s   |   dd¡ d S )Nzunhandled read eventrM   r‘   ri   r   r   r   r†   ß  s    zdispatcher.handle_readc                 C   s   |   dd¡ d S )Nzunhandled write eventrM   r‘   ri   r   r   r   rŠ   â  s    zdispatcher.handle_writec                 C   s   |   dd¡ d S )Nzunhandled connect eventrM   r‘   ri   r   r   r   rˆ   å  s    zdispatcher.handle_connectc                 C   s   |   ¡ }|d k	r| j|Ž  d S r   )rt   Úhandle_accepted)rW   Zpairr   r   r   r…   è  s    zdispatcher.handle_acceptc                 C   s   |  ¡  |  dd¡ d S )Nzunhandled accepted eventrM   )r{   r„   )rW   rX   rT   r   r   r   r’   í  s    zdispatcher.handle_acceptedc                 C   s   |   dd¡ |  ¡  d S )Nzunhandled close eventrM   )r„   r{   ri   r   r   r   r,   ñ  s    zdispatcher.handle_close)NN)N)N)N)r   ),r   r   r   ÚdebugrS   r:   rq   ÚclosingrT   Ú	frozensetr‚   rY   ra   rb   rU   rV   ZAF_INETZSOCK_STREAMrd   rR   rj   r7   r8   ro   rp   rs   rt   rv   rz   r{   r€   r„   r   rr   r#   r%   r   r‹   r†   rŠ   rˆ   r…   r’   r,   r   r   r   r   rL   Ò   sJ   

 

	

rL   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  | ||¡ d| _d S )Nry   )rL   rY   Ú
out_bufferrf   r   r   r   rY   ü  s    zdispatcher_with_send.__init__c                 C   s.   d}t  | | jd d… ¡}| j|d … | _d S )Nr   i   )rL   rv   r—   )rW   Znum_sentr   r   r   Úinitiate_send   s    z"dispatcher_with_send.initiate_sendc                 C   s   |   ¡  d S r   )r˜   ri   r   r   r   rŠ     s    z!dispatcher_with_send.handle_writec                 C   s   | j  pt| jƒS r   )rS   Úlenr—   ri   r   r   r   r8     s    zdispatcher_with_send.writablec                 C   s0   | j r|  dt|ƒ ¡ | j| | _|  ¡  d S )Nz
sending %s)r“   r„   r^   r—   r˜   )rW   rw   r   r   r   rv     s    zdispatcher_with_send.send)NN)r   r   r   rY   r˜   rŠ   r8   rv   r   r   r   r   r–   ú  s
   
r–   c                  C   s‚   t  ¡ \} }}g }|stdƒ‚|rL| |jjj|jjjt|j	ƒf¡ |j
}q~|d \}}}d dd„ |D ƒ¡}|||f| ||fS )Nztraceback does not existéÿÿÿÿr[   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ÚAssertionErrorr9   Útb_frameÚf_codeÚco_filenameÚco_namer~   Ú	tb_linenoÚtb_nextr_   )rŽ   r   Útbr   ÚfileZfunctionÚliner   r   r   r   r     s    ýr   c                 C   s”   | d krt } t|  ¡ ƒD ]n}z| ¡  W q tk
r` } z|jd tkrJn|sP‚ W 5 d }~X Y q tk
rt   ‚ Y q   |s€‚ Y qX q|  ¡  d S r'   )	r4   r5   Úvaluesr{   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  |¡| _d S r   )r   ÚduprB   ©rW   rB   r   r   r   rY   N  s    zfile_wrapper.__init__c                 C   s*   | j dkrtjd|  t| d |  ¡  d S )Nr   zunclosed file %r)Úsource)rB   ÚwarningsÚwarnÚResourceWarningr{   ri   r   r   r   Ú__del__Q  s
    
ÿzfile_wrapper.__del__c                 G   s   t j| jf|žŽ S r   )r   r"   rB   ©rW   r.   r   r   r   rz   W  s    zfile_wrapper.recvc                 G   s   t j| jf|žŽ S r   )r   r$   rB   rµ   r   r   r   rv   Z  s    zfile_wrapper.sendNc                 C   s(   |t jkr|t jkr|sdS tdƒ‚d S )Nr   z-Only asyncore specific behaviour implemented.)rV   rg   r‡   ÚNotImplementedError)rW   ÚlevelZoptnameZbuflenr   r   r   rh   ]  s    
ÿþzfile_wrapper.getsockoptc                 C   s(   | j dk rd S | j }d| _ t |¡ d S )Nr   rš   )rB   r   r{   r¯   r   r   r   r{   h  s
    
zfile_wrapper.closec                 C   s   | j S r   )rB   ri   r   r   r   re   o  s    zfile_wrapper.fileno)N)r   r   r   rY   r´   rz   rv   rh   r"   r$   r{   re   r   r   r   r   r­   I  s   
r­   c                   @   s   e Zd Zddd„Zdd„ ZdS )Úfile_dispatcherNc                 C   sP   t  | d |¡ d| _z| ¡ }W n tk
r4   Y nX |  |¡ t |d¡ d S )NTF)rL   rY   rS   re   ÚAttributeErrorÚset_filer   Úset_blocking)rW   rB   r?   r   r   r   rY   t  s    
zfile_dispatcher.__init__c                 C   s"   t |ƒ| _| j ¡ | _|  ¡  d S r   )r­   rV   re   rP   rb   r¯   r   r   r   rº     s    
zfile_dispatcher.set_file)N)r   r   r   rY   rº   r   r   r   r   r¸   r  s   
r¸   )r3   N)r3   N)rG   FNN)NF).Ú__doc__r(   rV   r|   r;   r±   r   Úerrnor   r   r   r   r   r   r   r	   r
   r   r   r   r   r•   r/   r4   r   r   Ú	Exceptionr   ÚKeyboardInterruptÚ
SystemExitr   r"   r$   r&   r2   rC   rF   Zpoll3rK   rL   r–   r   r«   rn   r­   r¸   r   r   r   r   Ú<module>   sD   <ÿ


'

  *
)