
][\                 @   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 r e	 d g 7Z	 Gd	 d   d e  Z n# e	 d
 g 7Z	 Gd d
   d
 e  Z Gd d   d e  Z e   Z e j Z d S)    N   )process)	reduction)utilstopZ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:   | j        f d d   } t j |   j  |  _ d  S)Nc                s      j  |  } |  j |  d  S)N)shareZ
send_bytes)connpidr   )new_sock 5/usr/lib/python3.4/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   s8   t  j |  j    } | j   } t j |  SWd QXd 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                sL   t  j |      f d d   }   f d d   } t j | |  |  _ d  S)Nc                s   t  j |    |  d  S)N)r   Zsend_handle)r	   r
   )new_fdr   r   r   1   s    zDupFd.__init__.<locals>.sendc                  s   t  j    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 |  j   } t j |  SWd QXd 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               @   ss   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 j   |  _ d  |  _ d  |  _ d  |  _ t	 j
 |  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   se   |  j  V |  j d k r& |  j   n  |  j d 7_ | | f |  j |  j <|  j |  j f SWd QXd 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   sT   d d l  m } |  \ } } | | d t j   j } | j | t j   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 d t j   j } | j d  | j   |  j	 j
 |  |  j	 j   r t j d  n  |  j j   d |  _	 d |  _ d |  _ x* |  j j   D] \ } \ } } |   q W|  j j   n  Wd QXd S)z:Stop the background thread and clear registered resources.r   )r-   Nr.   z._ResourceSharer thread did not stop when asked)r/   r-   r'   r)   r   r0   r.   r   r   r*   joinZis_aliver   Zsub_warningr(   r#   itemsclear)r   Ztimeoutr-   r4   r3   r   r   r   r   r   r   [   s"    

			"z_ResourceSharer.stopc             C   s   x* |  j  j   D] \ } \ } } |   q W|  j  j   |  j j |  j  t j   |  _ |  j d  k	 r{ |  j j	   n  d  |  _ d  |  _
 d  |  _ d  S)N)r#   r6   r7   r$   appendr'   r%   r&   r(   r   r)   r*   )r   r3   r   r   r   r   r   r+   p   s    "		z_ResourceSharer._afterforkc             C   s   d d l  m } |  j d  k s% t  t j d  | d t j   j  |  _ |  j j	 |  _
 t j d |  j  } d | _ | j   | |  _ d  S)Nr   )Listenerz0starting listener and thread for sending handlesr.   targetT)r/   r9   r(   AssertionErrorr   debugr   r0   r.   r2   r)   r%   ZThread_serveZdaemonstartr*   )r   r9   tr   r   r   r,   ~   s    	
z_ResourceSharer._startc             C   s   t  t d  r1 t j t j t d t j   n  x yx |  j j   c } | j   } | d  k re Pn  | \ } } |  j	 j
 |  \ } } z | | |  Wd  |   XWd  QXWq4 t j   s t j t j     n  Yq4 Xq4 d  S)Npthread_sigmaskr   )hasattrsignalr@   	SIG_BLOCKrangeNSIGr(   ZacceptZrecvr#   popr   Z
is_exitingsys
excepthookexc_info)r   r	   msgr3   Zdestination_pidr   r   r   r   r   r=      s     "z_ResourceSharer._serve)r   r   r   r   r   r   staticmethodr   r   r+   r,   r=   r   r   r   r   r!   =   s   
		r!   )r   rB   r   rG   r%    r   r   r   __all__platformobjectr   r   r!   r   r   r   r   r   r   <module>   s    	`	