U
    ‰dš   ã                   @   s  d dl mZ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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
lmZ ddddgZdZe d¡ZG dd„ deƒZddd„Z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 )é    )Úabsolute_importÚprint_functionNé   )Ú
connection)Úprocess)Ú	reduction)Úsemaphore_tracker)Úspawn)Úutil)Úspawnv_passfdsÚensure_runningÚget_inherited_fdsÚconnect_to_new_processÚset_forkserver_preloadé   ÚQc                   @   s4   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 ¡ | _dg| _d S )NÚ__main__)Ú_forkserver_addressÚ_forkserver_alive_fdÚ_inherited_fdsÚ	threadingÚLockÚ_lockÚ_preload_modules©Úself© r   ú7/tmp/pip-unpacked-wheel-lulkwrw3/billiard/forkserver.pyÚ__init__&   s
    
zForkServer.__init__c                 C   s&   t dd„ | jD ƒƒstdƒ‚|| _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 )z”Return 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   3   s    zForkServer.get_inherited_fdsc              
   C   sà   |   ¡  t|ƒd tkr tdƒ‚t tj¡ª}| | j¡ t 	¡ \}}t 	¡ \}}||| j
t ¡ g}||7 }zNz&t ||¡ ||fW W ¢4W  5 Q R £ S    t |¡ t |¡ ‚ Y nX W 5 t |¡ t |¡ X W 5 Q R X d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_UNIXÚconnectr   ÚosÚpiper   r   ZgetfdÚcloser   Zsendfds)r   ÚfdsÚclientZparent_rÚchild_wÚchild_rZparent_wZallfdsr   r   r   r   ;   s(    ÿ


z!ForkServer.connect_to_new_processc           
         sH  | j 6 t ¡  | jdk	r*W 5 Q R £ dS d}| jr^ddh‰ t d¡}‡ fdd„| ¡ D ƒ}ni }t tj	¡Æ}t
 d¡}| |¡ t |d	¡ | ¡  t ¡ \}}zrzT| ¡ |g}|| ¡ || j|f; }t ¡ }|gt ¡  }	|	d
|g7 }	t||	|ƒ W n   t |¡ ‚ Y nX W 5 t |¡ X || _|| _W 5 Q R X W 5 Q R X dS )zíMake 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 billiard.forkserver import main; main(%d, %d, %r, **%r)Ú	main_pathÚsys_pathÚignorec                    s   i | ]\}}|ˆ kr||“qS r   r   )r#   ÚxÚy©Zdesired_keysr   r   Ú
<dictcomp>j   s      z-ForkServer.ensure_running.<locals>.<dictcomp>r-   i€  z-c)r   r   r   r   r   r	   Zget_preparation_dataÚitemsr,   r-   r   Zarbitrary_addressÚbindr/   ÚchmodÚlistenr0   r1   ÚfilenoÚget_executabler
   Ú_args_from_interpreter_flagsr   r   )
r   ÚcmdÚdataÚlistenerÚaddressÚalive_rZalive_wZfds_to_passZexeÚargsr   r;   r   r   X   sB    



ÿ

ÿ
zForkServer.ensure_runningN)Ú__name__Ú
__module__Ú__qualname__r   r   r   r   r   r   r   r   r   r   $   s
   r   c                 C   s  |rdd|kr8|dk	r8dt  ¡ _zt |¡ W 5 t  ¡ `X |D ]&}zt|ƒ W q< tk
r`   Y q<X q<tjdk	r¢ztj 	¡  t
tjƒt_W n ttfk
r    Y nX t tjtj¡}tjtj| dJ}t ¡ 4}| ¡ t_| |tj¡ | |tj¡ zÐdd„ | ¡ D ƒ}	|	rúqqú||	kr:t |d¡dks6t‚t‚||	ksHt‚| ¡ d	 l}
d}t  ¡ d	kr¼zFzt"|
|||ƒ W n. t#k
rª   tj$t %¡ Ž  tj& '¡  Y nX W 5 t !|¡ X W 5 Q R X W qø tk
rü } z|j(t(j)krì‚ W 5 d}~X Y qøX qøW 5 Q R X W 5 Q R X dS )
zRun forkserver.r   NT)rA   c                 S   s   g | ]\}}|j ‘qS r   )Úfileobj)r#   ÚkeyÚeventsr   r   r   Ú
<listcomp>°   s     zmain.<locals>.<listcomp>r   ó    r   )*r   Úcurrent_processZ_inheritingr	   Zimport_main_pathÚ
__import__ÚImportErrorÚsysÚstdinr1   Úopenr/   ÚdevnullÚOSErrorr+   ÚsignalÚSIGCHLDÚSIG_IGNr,   r-   Ú	selectorsÚDefaultSelectorÚgetsocknameÚ_forkserverr   ÚregisterÚ
EVENT_READÚselectÚreadÚAssertionErrorÚ
SystemExitÚacceptÚforkÚ_exitÚ
_serve_oneÚ	ExceptionÚ
excepthookÚexc_infoÚstderrÚflushÚerrnoÚECONNABORTED)Zlistener_fdrH   Zpreloadr6   r7   ÚmodnameÚhandlerrF   ÚselectorZrfdsÚsÚcodeÚer   r   r   ÚmainŽ   sZ    



ÿ

rx   c                 G   s   | ||||fS r    r   )r5   r4   ÚaliveÚstfdZ	inheritedr   r   r   Ú__unpack_fdsÉ   s    r{   c           
      C   s¦   |  ¡  t  |¡ t tj|¡ t | td ¡}|   ¡  t|ƒtksHt‚t	|Ž \}}t
_}t
_|tj_t|t ¡ ƒ dtjkrŽdd l}| ¡  t |¡}	t||	ƒ d S )Nr   Úrandomr   )r1   r/   rZ   r[   r   Zrecvfdsr*   r)   re   r{   r`   r   r   r   Z_semaphore_trackerZ_fdÚwrite_unsignedÚgetpidrU   Úmodulesr|   Úseedr	   Ú_main)
ru   rF   rH   rs   r2   r5   r4   rz   r|   rv   r   r   r   rj   Í   s"    
ÿ
 

rj   c                 C   sN   d}t j}t|ƒ|k r@t | |t|ƒ ¡}|s6tdƒ‚||7 }q
t  |¡d S )NrQ   zunexpected EOFr   )ÚUNSIGNED_STRUCTÚsizer)   r/   rd   ÚEOFErrorÚunpack)ÚfdrE   Úlengthru   r   r   r   Úread_unsignedï   s    
rˆ   c                 C   s<   t  |¡}|r8t | |¡}|dkr*tdƒ‚||d … }q
d S )Nr   zshould not get here)r‚   Úpackr/   ÚwriteÚRuntimeError)r†   ÚnÚmsgÚnbytesr   r   r   r}   ú   s    
r}   )NN)$Ú
__future__r   r   rp   r/   r]   rZ   r,   ÚstructrU   r   Ú r   r   r   r   r	   r
   Úcompatr   Ú__all__r*   ÚStructr‚   Úobjectr   rx   r{   rj   rˆ   r}   r`   r   r   r   r   r   r   r   r   Ú<module>   s>   ÿ
j
;"