B
    2*™\„  ã               @   s²   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rxe
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 )é    Né   )Ú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	   )Únew_sock© úJC:\ALexclude\prg\programme\Python37\Lib\multiprocessing\resource_sharer.pyÚsend   s    
z DupSocket.__init__.<locals>.send)ÚdupÚ_resource_sharerÚregisterÚcloseÚ_id)ÚselfZsockr   r   )r   r   Ú__init__   s    zDupSocket.__init__c          	   C   s*   t  | j¡}| ¡ }t |¡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 )N)r   Zsend_handle)r
   r   )Únew_fdr   r   r   1   s    zDupFd.__init__.<locals>.sendc                  s   t  ˆ ¡ d S )N)Úosr   r   )r   r   r   r   3   s    zDupFd.__init__.<locals>.close)r    r   r   r   r   )r   Úfdr   r   r   )r   r   r   /   s    
zDupFd.__init__c          	   C   s"   t  | j¡}t |¡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   7   s    zDupFd.detachN)r   r   r   r   r   r   r   r   r   r   r   -   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   ?   s    
z_ResourceSharer.__init__c          	   C   sN   | j > | jdkr|  ¡  |  jd7  _||f| j| j< | j| jfS Q R X dS )z+Register resource, returning an identifier.Nr   )r(   r*   Ú_startr#   r$   )r   r   r   r   r   r   r   I   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)Ú
connectionr.   r   Úcurrent_processr/   r   r    Úgetpid)Zidentr.   ÚaddressÚkeyÚcr   r   r   r   R   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| _x | j ¡ D ]\}\}}|ƒ  qŒW | j ¡  W dQ R X dS )z:Stop the background thread and clear registered resources.r   )r.   N)r/   z._ResourceSharer thread did not stop when asked)r0   r.   r(   r*   r   r1   r/   r   r   r+   ÚjoinZis_aliver   Zsub_warningr)   r$   ÚitemsÚclear)r   Ztimeoutr.   r5   r4   r   r   r   r   r   r   [   s"    





z_ResourceSharer.stopc             C   sn   x | j  ¡ D ]\}\}}|ƒ  qW | j  ¡  | j | j¡ t ¡ | _| jd k	rX| j 	¡  d | _d | _
d | _d S )N)r$   r7   r8   r%   Úappendr(   r&   r'   r)   r   r*   r+   )r   r4   r   r   r   r   r   r,   p   s    




z_ResourceSharer._afterforkc             C   sX   ddl m} t d¡ |t ¡ jd| _| jj| _	t
j| jd}d|_| ¡  || _d S )Nr   )ÚListenerz0starting listener and thread for sending handles)r/   )ÚtargetT)r0   r:   r   Údebugr   r1   r/   r)   r3   r*   r&   ZThreadÚ_serveZdaemonÚstartr+   )r   r:   Útr   r   r   r-   ~   s    

z_ResourceSharer._startc          	   C   sª   t tdƒr t tjtdtjƒ¡ x„y\| j ¡ H}| ¡ }|d krBP |\}}| j	 
|¡\}}z|||ƒ W d |ƒ  X W d Q R X W q"   t ¡ sœtjt ¡ Ž  Y q"X q"W d S )NÚpthread_sigmaskr   )ÚhasattrÚsignalr@   Z	SIG_BLOCKÚrangeÚNSIGr)   ZacceptZrecvr$   Úpopr   Z
is_exitingÚsysÚ
excepthookÚexc_info)r   r
   Úmsgr4   Zdestination_pidr   r   r   r   r   r=   ‰   s     
z_ResourceSharer._serve)N)r   r   r   r   r   r   Ústaticmethodr   r   r,   r-   r=   r   r   r   r   r"   =   s   
		
r"   )r    rB   r   rF   r&   Ú r   Úcontextr   r   Ú__all__ÚplatformÚobjectr   r   r"   r   r   r   r   r   r   Ú<module>   s    


`