U
    Íø.eî  ã                   @   s¢   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d	gZG d
d„ dƒZeƒ ZejZejZejZejZdd„ ZdS )é    Né   )Ú	_billiard)Úspawn)Úutil)Úspawnv_passfdsÚensure_runningÚregisterÚ
unregisterc                   @   s<   e Zd Zdd„ Zdd„ Zdd„ Zdd„ Zd	d
„ Zdd„ ZdS )ÚSemaphoreTrackerc                 C   s   t  ¡ | _d | _d S ©N)Ú	threadingÚLockÚ_lockÚ_fd©Úself© r   ú>/tmp/pip-unpacked-wheel-39f38r4u/billiard/semaphore_tracker.pyÚ__init__    s    
zSemaphoreTracker.__init__c                 C   s   |   ¡  | jS r   )r   r   r   r   r   r   Úgetfd$   s    zSemaphoreTracker.getfdc              
   C   sÞ   | j Î | jdk	r W 5 Q R £ dS g }z| tj ¡ ¡ W n tk
rL   Y nX d}t ¡ \}}zdz@| |¡ t
 ¡ }|gt ¡  }|d|| g7 }t|||ƒ W n   t 	|¡ ‚ Y nX || _W 5 t 	|¡ X W 5 Q R X dS )z®Make sure that semaphore tracker process is running.

        This can be run from any process.  Usually a child process will use
        the semaphore created by its parent.Nz4from billiard.semaphore_tracker import main;main(%d)z-c)r   r   ÚappendÚsysÚstderrÚfilenoÚ	ExceptionÚosÚpipeÚcloser   Úget_executabler   Ú_args_from_interpreter_flagsr   )r   Zfds_to_passÚcmdÚrÚwZexeÚargsr   r   r   r   (   s*    



zSemaphoreTracker.ensure_runningc                 C   s   |   d|¡ dS )z2Register name of semaphore with semaphore tracker.ZREGISTERN©Ú_send©r   Únamer   r   r   r   F   s    zSemaphoreTracker.registerc                 C   s   |   d|¡ dS )z4Unregister name of semaphore with semaphore tracker.Z
UNREGISTERNr$   r&   r   r   r   r	   J   s    zSemaphoreTracker.unregisterc                 C   sP   |   ¡  d ||¡ d¡}t|ƒdkr.tdƒ‚t | j|¡}|t|ƒksLt‚d S )Nz{0}:{1}
Úasciii   zname too long)	r   ÚformatÚencodeÚlenÚ
ValueErrorr   Úwriter   ÚAssertionError)r   r    r'   ÚmsgÚnbytesr   r   r   r%   N   s    zSemaphoreTracker._sendN)	Ú__name__Ú
__module__Ú__qualname__r   r   r   r   r	   r%   r   r   r   r   r
      s   r
   c                 C   s   t   t jt j¡ t   t jt j¡ tjtjfD ]&}z| ¡  W q, tk
rP   Y q,X q,t	ƒ }z¦t | d¡}|D ]„}zJ| ¡  d¡\}}|dkrš| |¡ n |dkr®| |¡ ntd	| ƒ‚W qn tk
rð   ztjt ¡ Ž  W n   Y nX Y qnX qnW 5 Q R X W 5 |r6zt
 dt|ƒ ¡ W n tk
r4   Y nX |D ]^}zT| d¡}zt |¡ W n6 tk
rŽ } zt
 d||f ¡ W 5 d}~X Y nX W 5 X q:X dS )
zRun semaphore tracker.zRsemaphore_tracker: There appear to be %d leaked semaphores to clean up at shutdownr(   zsemaphore_tracker: %r: %sNÚrbó   :s   REGISTERs
   UNREGISTERzunrecognized command %r)ÚsignalÚSIGINTÚSIG_IGNÚSIGTERMr   ÚstdinÚstdoutr   r   ÚsetÚwarningsÚwarnr+   Údecoder   Z
sem_unlinkÚioÚopenÚstripÚsplitÚaddÚremoveÚRuntimeErrorÚ
excepthookÚexc_info)ÚfdÚfÚcacher'   ÚeÚliner    r   r   r   Úmain`   sL    þ

(rN   )r@   r   r6   r   r   r=   Z_extr   Ú r   r   Úcompatr   Ú__all__r
   Z_semaphore_trackerr   r   r	   r   rN   r   r   r   r   Ú<module>   s"   
;