U
    ‰dñ  ã                   @   s¾   d dl m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gZejdkr„ed	g7 ZG d
d	„ d	eƒZnedg7 ZG dd„ deƒZG dd„ deƒZeƒ ZejZdS )é    )Úabsolute_importNé   )Úprocess)Ú	reduction)ÚutilÚstopÚwin32Ú	DupSocketc                   @   s    e Zd ZdZdd„ Zdd„ ZdS )r	   zPicklable wrapper for a socket.c                    s(   |  ¡ ‰ ‡ fdd„}t |ˆ j¡| _d S )Nc                    s   ˆ   |¡}|  |¡ d S ©N)ÚshareZ
send_bytes)ÚconnÚpidr   ©Znew_sock© ú</tmp/pip-unpacked-wheel-lulkwrw3/billiard/resource_sharer.pyÚsend"   s    
z DupSocket.__init__.<locals>.send)ÚdupÚ_resource_sharerÚregisterÚcloseÚ_id)ÚselfÚsockr   r   r   r   Ú__init__   s    zDupSocket.__init__c              
   C   s6   t  | j¡ }| ¡ }t |¡W  5 Q R £ S Q R X dS )z1Get the socket.  This should only be called once.N)r   Úget_connectionr   Z
recv_bytesÚsocketZ	fromshare)r   r   r   r   r   r   Údetach'   s    zDupSocket.detachN©Ú__name__Ú
__module__Ú__qualname__Ú__doc__r   r   r   r   r   r   r	      s   ÚDupFdc                   @   s    e Zd ZdZdd„ Zdd„ ZdS )r"   z-Wrapper for fd which can be used at any time.c                    s4   t  |¡‰ ‡ fdd„}‡ fdd„}t ||¡| _d S )Nc                    s   t  | ˆ |¡ d S r
   )r   Zsend_handle)r   r   ©Znew_fdr   r   r   5   s    zDupFd.__init__.<locals>.sendc                      s   t  ˆ ¡ d S r
   )Úosr   r   r#   r   r   r   8   s    zDupFd.__init__.<locals>.close)r$   r   r   r   r   )r   Úfdr   r   r   r#   r   r   2   s    
zDupFd.__init__c              
   C   s.   t  | j¡}t |¡W  5 Q R £ S Q R X dS )z-Get the fd.  This should only be called once.N)r   r   r   r   Zrecv_handle)r   r   r   r   r   r   <   s    zDupFd.detachNr   r   r   r   r   r"   0   s   
c                   @   sN   e Zd ZdZdd„ Zdd„ Zedd„ ƒZdd	d
„Zdd„ Z	dd„ Z
dd„ ZdS )Ú_ResourceSharerz-Manager for resouces using background thread.c                 C   s@   d| _ i | _g | _t ¡ | _d | _d | _d | _t	 
| tj¡ d S )Nr   )Ú_keyÚ_cacheÚ
_old_locksÚ	threadingÚLockÚ_lockÚ	_listenerÚ_addressÚ_threadr   Zregister_after_forkr&   Ú
_afterfork)r   r   r   r   r   D   s    
z_ResourceSharer.__init__c              
   C   sZ   | j J | jdkr|  ¡  |  jd7  _||f| j| j< | j| jfW  5 Q R £ S Q R X dS )z+Register resource, returning an identifier.Nr   )r,   r.   Ú_startr'   r(   )r   r   r   r   r   r   r   N   s    
z_ResourceSharer.registerc                 C   s<   ddl m} | \}}||t ¡ jd}| |t ¡ f¡ |S )z<Return connection from which to receive identified resource.r   ©ÚClient©Úauthkey)Ú
connectionr3   r   Úcurrent_processr5   r   r$   Úgetpid)Úidentr3   ÚaddressÚkeyÚcr   r   r   r   W   s
    z_ResourceSharer.get_connectionNc              	   C   s¶   ddl m} | jš | jdk	r¨|| jt ¡ jd}| d¡ | ¡  | j	 
|¡ | j	 ¡ rdt d¡ | j ¡  d| _	d| _d| _| j ¡ D ]\}\}}|ƒ  qŠ| j ¡  W 5 Q R X dS )z:Stop the background thread and clear registered resources.r   r2   Nr4   z._ResourceSharer thread did not stop when asked)r6   r3   r,   r.   r   r7   r5   r   r   r/   ÚjoinÚis_aliver   Zsub_warningr-   r(   ÚitemsÚclear)r   Útimeoutr3   r<   r;   r   r   r   r   r   r   `   s$    
ÿ



z_ResourceSharer.stopc                 C   sj   | j  ¡ D ]\}\}}|ƒ  q
| j  ¡  | j | j¡ t ¡ | _| jd k	rT| j 	¡  d | _d | _
d | _d S r
   )r(   r?   r@   r)   Úappendr,   r*   r+   r-   r   r.   r/   )r   r;   r   r   r   r   r   r0   u   s    



z_ResourceSharer._afterforkc                 C   sf   ddl m} | jd kst‚t d¡ |t ¡ jd| _| jj	| _
tj| jd}d|_| ¡  || _d S )Nr   )ÚListenerz0starting listener and thread for sending handlesr4   )ÚtargetT)r6   rC   r-   ÚAssertionErrorr   Údebugr   r7   r5   r:   r.   r*   ÚThreadÚ_serveÚdaemonÚstartr/   )r   rC   Útr   r   r   r1   ƒ   s    

z_ResourceSharer._startc              	   C   s²   t tdƒr t tjtdtjƒ¡ zh| j ¡ T}| ¡ }|d krLW 5 Q R £ W q®|\}}| j	 
|¡\}}z|||ƒ W 5 |ƒ  X W 5 Q R X W q    t ¡ s¦tjt ¡ Ž  Y q X q d S )NÚpthread_sigmaskr   )ÚhasattrÚsignalrL   Ú	SIG_BLOCKÚrangeÚNSIGr-   ÚacceptÚrecvr(   Úpopr   Z
is_exitingÚsysÚ
excepthookÚexc_info)r   r   Úmsgr;   Zdestination_pidr   r   r   r   r   rH   Ž   s    
z_ResourceSharer._serve)N)r   r   r    r!   r   r   Ústaticmethodr   r   r0   r1   rH   r   r   r   r   r&   B   s   
	

r&   )Ú
__future__r   r$   rN   r   rU   r*   Ú r   r   r   Ú__all__ÚplatformÚobjectr	   r"   r&   r   r   r   r   r   r   Ú<module>
   s"   


`