U
    ‰d  ã                   @   s°   d dl 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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eƒZeƒ ZejZejZejZejZdd„ ZdS )é    )Úabsolute_importNé   )Ú	_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-lulkwrw3/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	   G   s    zSemaphoreTracker.registerc                 C   s   |   d|¡ dS )z4Unregister name of semaphore with semaphore tracker.Z
UNREGISTERNr%   r'   r   r   r   r
   K   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&   O   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   Úmaina   sL    þ

(rO   )Ú
__future__r   rA   r   r7   r   r   r>   Z_extr   Ú r   r   Úcompatr   Ú__all__Úobjectr   Z_semaphore_trackerr   r	   r
   r   rO   r   r   r   r   Ú<module>   s$   
;