
][\!                 @   sd  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 Z d  d l Z d d l m	 Z	 d d l m
 Z
 d d l m Z d d l m Z d d l m Z d d l m Z d	 d
 d d g Z d Z e j d  Z Gd d   d e  Z d d d d  Z d d   Z d d   Z d d   Z e   Z e j Z e j Z e j Z e j Z d S)    N   )
connection)process)	reduction)semaphore_tracker)spawn)utilensure_runningget_inherited_fdsconnect_to_new_processset_forkserver_preload   Qc               @   sL   e  Z d  Z d d   Z d d   Z d d   Z d d   Z d	 d
   Z d S)
ForkServerc             C   s:   d  |  _  d  |  _ d  |  _ t j   |  _ d g |  _ d  S)N__main__)_forkserver_address_forkserver_alive_fd_inherited_fds	threadingZLock_lock_preload_modules)self r   0/usr/lib/python3.4/multiprocessing/forkserver.py__init__!   s
    			zForkServer.__init__c             C   s8   t  d d   |  j D  s+ t d   n  | |  _ d S)z>Set list of module names to try to load in forkserver process.c             s   s!   |  ] } t  |  t k Vq d  S)N)typestr).0modr   r   r   	<genexpr>*   s    z4ForkServer.set_forkserver_preload.<locals>.<genexpr>z&module_names must be a list of stringsN)allr   	TypeError)r   Zmodules_namesr   r   r   r   (   s    z!ForkServer.set_forkserver_preloadc             C   s   |  j  S)zReturn list of fds inherited from parent process.

        This returns None if the current process was not started by fork
        server.
        )r   )r   r   r   r   r
   .   s    zForkServer.get_inherited_fdsc             C   s  |  j    t |  d t k r/ t d   n  t j t j   } | j |  j  t j	   \ } } t j	   \ } } | | |  j
 t j   g } | | 7} zJ y t j | |  | | f SWn% t j |  t j |    Yn XWd t j |  t j |  XWd QXd S)a;  Request forkserver to create a child process.

        Returns a pair of fds (status_r, data_w).  The calling process can read
        the child process's pid and (eventually) its returncode from status_r.
        The calling process should write to data_w the pickled preparation and
        process data.
           ztoo many fdsN)r	   lenMAXFDS_TO_SEND
ValueErrorsocketAF_UNIXZconnectr   ospiper   r   Zgetfdr   Zsendfdsclose)r   fdsZclientZparent_rchild_wchild_rZparent_wZallfdsr   r   r   r   6   s&    

z!ForkServer.connect_to_new_processc                s  |  j  t j   |  j d k	 r' d Sd d } |  j r} d d h   t j d  } t   f d d   | j   D  } n i  } t	 j	 t	 j
  } t j d	  } | j |  t j | d
  | j d  t j   \ } } z yy | j   | g } | | j   | |  j | f ;} t j   } | g t j   }	 |	 d | g 7}	 t j | |	 |  }
 Wn t j |    Yn XWd t j |  X| |  _ | |  _ Wd QXWd QXd S)zMake sure that a fork server is running.

        This can be called from any process.  Note that usually a child
        process will just reuse the forkserver started by its parent, so
        ensure_running() will do nothing.
        Nz-from multiprocessing.forkserver import main; zmain(%d, %d, %r, **%r)	main_pathsys_pathignorec             3   s-   |  ]# \ } } |   k r | | f Vq d  S)Nr   )r   xy)desired_keysr   r   r   e   s    	z,ForkServer.ensure_running.<locals>.<genexpr>r'   i  d   z-c)r   r   r	   r   r   r   Zget_preparation_datadictitemsr&   r'   r   Zarbitrary_addressZbindr(   chmodZlistenr)   filenoZget_executabler   Z_args_from_interpreter_flagsZspawnv_passfdsr*   r   )r   cmddatalistenerZaddressalive_rZalive_wZfds_to_passZexeargspidr   )r3   r   r	   S   s>    

	(
	zForkServer.ensure_runningN)__name__
__module____qualname__r   r   r
   r   r	   r   r   r   r   r      s
   r   c          <   C   s  | r d | k rQ | d k	 rQ d t  j   _ z t j |  Wd t  j   ` Xn  x4 | D]) } y t |  WqX t k
 r YqX XqX Wn  t j d k	 r y# t j j	   t
 t j  t _ Wq t t f k
 r Yq Xn  t j t j t j  } t j t j d |  } t j   } | j   t _ | j | t j  | j | t j  x[yx& d d   | j   D }	 |	 rXPqXqX| |	 k rt j | d  d k st  t  n  | |	 k st  | j   d	  }
 d } t j    d	 k rRzP y t! |
 | | |  Wn2 t" k
 r<t j# t j$     t j% j&   Yn XWd t j' |  Xn  Wd QXWqRt( k
 rmYqRt k
 r} z | j) t) j* k r  n  WYd d } ~ XqRXqRWd QXWd QXd S)
zRun forkserver.r   NTr8   c             S   s   g  |  ] \ } } | j   q Sr   )Zfileobj)r   keyZeventsr   r   r   
<listcomp>   s   	 zmain.<locals>.<listcomp>r       r   )+r   Zcurrent_processZ_inheritingr   Zimport_main_path
__import__ImportErrorsysstdinr*   openr(   devnullOSErrorr%   signalSIGCHLDSIG_IGNr&   r'   	selectorsZDefaultSelectorZgetsockname_forkserverr   registerZ
EVENT_READZselectreadAssertionError
SystemExitZacceptfork
_serve_one	Exception
excepthookexc_infostderrflush_exitInterruptedErrorerrnoZECONNABORTED)Zlistener_fdr<   Zpreloadr.   r/   modnamehandlerr;   ZselectorZrfdsscodeer   r   r   main   s^    	rd   c       
      C   s   | j    t j  |  t j t j |  t j |  t d  } |  j    t |  t k sb t  | ^ } } t	 _
 } t	 _ | t j _ t | t j    d t j k r d d  l } | j   n  t j |  }	 t | |	  d  S)Nr   randomr   )r*   r(   rL   rM   r   Zrecvfdsr$   r#   rS   rP   r   r   r   Z_semaphore_trackerZ_fdwrite_unsignedgetpidrG   modulesre   Zseedr   _main)
ra   r;   r<   r`   r+   r-   r,   Zstfdre   rb   r   r   r   rV      s    

rV   c             C   s   d } t  j } xq t |  | k  r x9 y  t j |  | t |   } Wn t k
 r[ Yq' XPq' | su t d   n  | | 7} q Wt  j |  d S)NrD   zunexpected EOFr   )UNSIGNED_STRUCTsizer#   r(   rR   r]   EOFErrorZunpack)fdr:   Zlengthra   r   r   r   read_unsigned   s    	 rn   c             C   s}   t  j |  } xg | rx x/ y t j |  |  } Wn t k
 rE Yq XPq | d k re t d   n  | | d   } q Wd  S)Nr   zshould not get here)rj   Zpackr(   writer]   RuntimeError)rm   nmsgnbytesr   r   r   rf      s    	rf   )r^   r(   rO   rL   r&   ZstructrG   r    r   r   r   r   r   r   __all__r$   ZStructrj   objectr   rd   rV   rn   rf   rP   r	   r
   r   r   r   r   r   r   <module>   s6   		h> 				