a
    zeN                     @   sf  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y   i ZY n0 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rbG 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   sF   zt | W S  tttfy@   | tv r4t|   Y S d|   Y S 0 d S )NzUnknown error %s)osstrerror
ValueErrorOverflowError	NameErrorr   )err r   /usr/lib/python3.9/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   s8   z|    W n& ty     Y n   |   Y n0 d S N)handle_read_event_reraised_exceptionshandle_errorobjr   r   r   readQ   s    r"   c                 C   s8   z|    W n& ty     Y n   |   Y n0 d S r   )handle_write_eventr   r   r    r   r   r   writeY   s    r$   c                 C   s8   z|    W n& ty     Y n   |   Y n0 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y } z,|jd tvr|   n| 
  W Y d }~n.d }~0  ty    Y n   |   Y n0 d S Nr   )selectPOLLINr   POLLOUTr#   POLLPRIr%   POLLHUPPOLLERRPOLLNVALhandle_closeOSErrorargs_DISCONNECTEDr   r   )r!   flagser   r   r   	readwritei   s"    



r5           c           	      C   s<  |d u rt }|r8g }g }g }t| D ]L\}}| }| }|rP|| |rd|jsd|| |sl|r*|| q*g |  kr|  kr|krn nt|  d S t		|||| \}}}|D ] }|
|}|d u rqt| q|D ]"}|
|}|d u rqt| q|D ]&}|
|}|d u r,qt| qd S r   )
socket_maplistitemsreadablewritableappend	acceptingtimesleepr(   getr"   r$   r&   )	timeoutmaprwr4   fdr!   Zis_rZis_wr   r   r   poll}   s@    


"







rF   c                 C   s   |d u rt }| d ur t| d } t }|rt| D ]L\}}d}| r\|tjtjB O }|	 rt|j
st|tjO }|r8||| q8|| }|D ]&\}}||}|d u rqt|| qd S )Ni  r   )r7   intr(   rF   r8   r9   r:   r)   r+   r;   r=   r*   registerr@   r5   )rA   rB   ZpollsterrE   r!   r3   rC   r   r   r   poll2   s(    


rI         >@Fc                 C   sb   |d u rt }|r ttdr t}nt}|d u r>|r^|| | q,n |r^|dkr^|| | |d }q>d S )NrF   r      )r7   hasattrr(   rI   rF   )rA   Zuse_pollrB   countZpoll_funr   r   r   loop   s    
rN   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 u rt | _n|| _d | _|r|d | || d| _z| | _W q ty } z2|j	d t
tfv rtd| _n| |  W Y d }~qd }~0 0 nd | _d S )NFTr   )r7   _map_filenosetblocking
set_socket	connectedgetpeernameaddrr0   r1   r   r   del_channelsocket)selfsockrB   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 urz|d| j  W n" ty~   |t| j Y n0 dd	|t
| f S )N.Z	listeningrU   z%s:%dz<%s at %#x> )	__class__r   r   r=   rW   r<   rU   	TypeErrorreprjoinid)rZ   statusr   r   r   __repr__   s    

zdispatcher.__repr__c                 C   s   |d u r| j }| || j< d S r   )rQ   rR   )rZ   rB   r   r   r   add_channel	  s    zdispatcher.add_channelc                 C   s,   | j }|d u r| j}||v r"||= d | _ d S r   )rR   rQ   )rZ   rB   rE   r   r   r   rX     s    zdispatcher.del_channelc                 C   s.   ||f| _ t||}|d | | d S )NF)Zfamily_and_typerY   rS   rT   )rZ   familytyper[   r   r   r   create_socket  s    

zdispatcher.create_socketc                 C   s   || _ | | _| | d S r   )rY   filenorR   rf   rZ   r[   rB   r   r   r   rT     s    
zdispatcher.set_socketc                 C   sB   z*| j t jt j| j t jt jdB  W n ty<   Y n0 d S )NrK   )rY   
setsockopt
SOL_SOCKETSO_REUSEADDR
getsockoptr0   rZ   r   r   r   set_reuse_addr#  s    
zdispatcher.set_reuse_addrc                 C   s   dS NTr   rp   r   r   r   r:   4  s    zdispatcher.readablec                 C   s   dS rr   r   rp   r   r   r   r;   7  s    zdispatcher.writablec                 C   s(   d| _ tjdkr|dkrd}| j|S )NTnt   )r=   r   namerY   listen)rZ   numr   r   r   rv   >  s    zdispatcher.listenc                 C   s   || _ | j|S r   )rW   rY   bind)rZ   rW   r   r   r   rx   D  s    zdispatcher.bindc                 C   sp   d| _ d| _| j|}|tttfv s8|tkrBtj	dkrB|| _
d S |dtfv r^|| _
|   nt|t| d S )NFTrs   r   )rU   
connectingrY   
connect_exr   r   r   r   r   ru   rW   r	   handle_connect_eventr0   r   )rZ   addressr   r   r   r   connectH  s    
zdispatcher.connectc              
   C   sz   z| j  \}}W nZ ty&   Y d S  tyl } z0|jd tttfv rVW Y d }~d S  W Y d }~nd }~0 0 ||fS d S r'   )rY   acceptr`   r0   r1   r   r   r   )rZ   connrW   whyr   r   r   r~   V  s    zdispatcher.acceptc              
   C   s~   z| j |}|W S  tyx } zN|jd tkr>W Y d }~dS |jd tv rb|   W Y d }~dS  W Y d }~n
d }~0 0 d S r'   )rY   sendr0   r1   r   r2   r/   )rZ   dataresultr   r   r   r   r   d  s    zdispatcher.sendc              
   C   sx   z(| j |}|s |   W dS |W S W nJ tyr } z2|jd tv r\|   W Y d }~dS  W Y d }~n
d }~0 0 d S )N    r   )rY   recvr/   r0   r1   r2   )rZ   Zbuffer_sizer   r   r   r   r   r   q  s    
zdispatcher.recvc              
   C   sp   d| _ d| _d| _|   | jd urlz| j  W n8 tyj } z |jd tt	fvrV W Y d }~n
d }~0 0 d S )NFr   )
rU   r=   ry   rX   rY   closer0   r1   r   r
   )rZ   r   r   r   r   r     s    
zdispatcher.closec                 C   s   t jdt|  d S )Nzlog: %s
)sysstderrr$   str)rZ   messager   r   r   log  s    zdispatcher.loginfoc                 C   s   || j vrtd||f  d S )Nz%s: %s)ignore_log_typesprint)rZ   r   rh   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_acceptrU   ry   r{   handle_readrp   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 )Nr   TF)	rY   ro   rm   SO_ERRORr0   r   handle_connectrU   ry   rZ   r   r   r   r   r{     s    zdispatcher.handle_connect_eventc                 C   s*   | j r
d S | js| jr|   |   d S r   )r=   rU   ry   r{   handle_writerp   r   r   r   r#     s    zdispatcher.handle_write_eventc                 C   s0   | j t jt j}|dkr$|   n|   d S r'   )rY   ro   rm   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0 | 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_tracebackra   rc   r   r/   )rZ   niltvtbinfoZ	self_reprr   r   r   r     s    	zdispatcher.handle_errorc                 C   s   |  dd d S )Nz!unhandled incoming priority eventrP   r   rp   r   r   r   r     s    zdispatcher.handle_exptc                 C   s   |  dd d S )Nzunhandled read eventrP   r   rp   r   r   r   r     s    zdispatcher.handle_readc                 C   s   |  dd d S )Nzunhandled write eventrP   r   rp   r   r   r   r     s    zdispatcher.handle_writec                 C   s   |  dd d S )Nzunhandled connect eventrP   r   rp   r   r   r   r     s    zdispatcher.handle_connectc                 C   s   |   }|d ur| j|  d S r   )r~   handle_accepted)rZ   Zpairr   r   r   r     s    zdispatcher.handle_acceptc                 C   s   |   | dd d S )Nzunhandled accepted eventrP   )r   r   )rZ   r[   rW   r   r   r   r     s    zdispatcher.handle_acceptedc                 C   s   |  dd |   d S )Nzunhandled close eventrP   )r   r   rp   r   r   r   r/     s    zdispatcher.handle_close)NN)N)N)N)r   ),r   r   r   debugrU   r=   ry   closingrW   	frozensetr   r\   re   rf   rX   rY   AF_INETSOCK_STREAMri   rT   rq   r:   r;   rv   rx   r}   r~   r   r   r   r   r   r   r{   r#   r%   r   r   r   r   r   r   r   r/   r   r   r   r   rO      sJ   

 

	

rO   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 )Nr   )rO   r\   
out_bufferrk   r   r   r   r\     s    zdispatcher_with_send.__init__c                 C   s.   d}t | | jd d }| j|d  | _d S )Nr   i   )rO   r   r   )rZ   Znum_sentr   r   r   initiate_send   s    z"dispatcher_with_send.initiate_sendc                 C   s   |    d S r   )r   rp   r   r   r   r     s    z!dispatcher_with_send.handle_writec                 C   s   | j  pt| jS r   )rU   lenr   rp   r   r   r   r;     s    zdispatcher_with_send.writablec                 C   s0   | j r| dt|  | j| | _|   d S )Nz
sending %s)r   r   ra   r   r   )rZ   r   r   r   r   r     s    zdispatcher_with_send.send)NN)r   r   r   r\   r   r   r;   r   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 existr^   c                 S   s   g | ]}d | qS )z
[%s|%s|%s]r   ).0xr   r   r   
<listcomp>&  r   z%compact_traceback.<locals>.<listcomp>)r   exc_infoAssertionErrorr<   tb_framef_codeco_filenameco_namer   	tb_linenotb_nextrb   )r   r   tbr   filefunctionliner   r   r   r   r     s    r   c                 C   s   | d u rt } t|  D ]n}z|  W q tyb } z"|jd tkrHn|sN W Y d }~qd }~0  tyt    Y q   |s Y q0 q|   d S r'   )	r7   r8   valuesr   r0   r1   r
   r   clear)rB   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   duprE   rZ   rE   r   r   r   r\   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)rE   warningswarnResourceWarningr   rp   r   r   r   __del__Q  s
    
zfile_wrapper.__del__c                 G   s   t j| jg|R  S r   )r   r"   rE   rZ   r1   r   r   r   r   W  s    zfile_wrapper.recvc                 G   s   t j| jg|R  S r   )r   r$   rE   r   r   r   r   r   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.)rY   rm   r   NotImplementedError)rZ   levelZoptnamebuflenr   r   r   ro   ]  s    
zfile_wrapper.getsockoptc                 C   s(   | j dk rd S | j }d| _ t| d S )Nr   r   )rE   r   r   r   r   r   r   r   h  s
    
zfile_wrapper.closec                 C   s   | j S r   )rE   rp   r   r   r   rj   o  s    zfile_wrapper.fileno)N)r   r   r   r\   r   r   r   ro   r"   r$   r   rj   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   sN   t | d | d| _z| }W n ty2   Y n0 | | t|d d S )NTF)rO   r\   rU   rj   AttributeErrorset_filer   set_blocking)rZ   rE   rB   r   r   r   r\   t  s    
zfile_dispatcher.__init__c                 C   s"   t || _| j | _|   d S r   )r   rY   rj   rR   rf   r   r   r   r   r     s    
zfile_dispatcher.set_file)N)r   r   r   r\   r   r   r   r   r   r   r  s   
r   )r6   N)r6   N)rJ   FNN)NF).__doc__r(   rY   r   r>   r   r   errnor   r   r   r   r   r   r   r	   r
   r   r   r   r   r   r2   r7   r   r   	Exceptionr   KeyboardInterrupt
SystemExitr   r"   r$   r&   r5   rF   rI   Zpoll3rN   rO   r   r   r   ru   r   r   r   r   r   r   <module>   sD   <


'

  *
)