B
    È S][  ã               @   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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 )é    Né   )Úspawn)ÚutilÚ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 | _d S )N)Ú	threadingZLockÚ_lockÚ_fdÚ_pid)Úself© r   ú2lib/python3.7/multiprocessing/semaphore_tracker.pyÚ__init__   s    
zSemaphoreTracker.__init__c             C   s   |   ¡  | jS )N)r   r   )r   r   r   r   Úgetfd"   s    zSemaphoreTracker.getfdc       	   
   C   s  | j  | jdk	rRt | jtj¡\}}|s0dS t | j¡ d| _d| _t d¡ g }y| 	t
j ¡ ¡ W n tk
r~   Y nX d}t ¡ \}}zlyB| 	|¡ t ¡ }|gt ¡  }|d|| g7 }t |||¡}W n   t |¡ ‚ Y nX || _|| _W dt |¡ X W d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.NzWsemaphore_tracker: process died unexpectedly, relaunching.  Some semaphores might leak.z;from multiprocessing.semaphore_tracker import main;main(%d)z-c)r
   r   ÚosÚwaitpidÚWNOHANGÚcloser   ÚwarningsÚwarnÚappendÚsysÚstderrÚfilenoÚ	ExceptionÚpiper   Zget_executabler   Z_args_from_interpreter_flagsZspawnv_passfds)	r   ÚpidZstatusZfds_to_passÚcmdÚrÚwZexeÚargsr   r   r   r   &   s8    





zSemaphoreTracker.ensure_runningc             C   s   |   d|¡ dS )z2Register name of semaphore with semaphore tracker.ZREGISTERN)Ú_send)r   Únamer   r   r   r   Q   s    zSemaphoreTracker.registerc             C   s   |   d|¡ dS )z4Unregister name of semaphore with semaphore tracker.Z
UNREGISTERN)r#   )r   r$   r   r   r   r   U   s    zSemaphoreTracker.unregisterc             C   s`   |   ¡  d ||¡ d¡}t|ƒdkr.tdƒ‚t | j|¡}|t|ƒks\td |t|ƒ¡ƒ‚d S )Nz{0}:{1}
Úasciii   zname too longznbytes {0:n} but len(msg) {1:n})	r   ÚformatÚencodeÚlenÚ
ValueErrorr   Úwriter   ÚAssertionError)r   r   r$   ÚmsgÚnbytesr   r   r   r#   Y   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¡ x6tjtjfD ]&}y| ¡  W q. tk
rR   Y q.X q.W t	ƒ }z¨t
| dƒ”}xŒ|D ]„}yJ| ¡  d¡\}}|dkrž| |¡ n |dkr²| |¡ ntd| ƒ‚W qr tk
rô   ytjt ¡ Ž  W n   Y nX Y qrX qrW W dQ R X W d|r<yt dt|ƒ ¡ W n tk
r:   Y nX xf|D ]^}zT| d¡}yt |¡ W n6 tk
r– } zt d	||f ¡ W dd}~X Y nX W dX qBW X dS )
zRun semaphore tracker.Úrbó   :s   REGISTERs
   UNREGISTERzunrecognized command %rNzRsemaphore_tracker: There appear to be %d leaked semaphores to clean up at shutdownr%   zsemaphore_tracker: %r: %s)ÚsignalÚSIGINTÚSIG_IGNÚSIGTERMr   ÚstdinÚstdoutr   r   ÚsetÚopenÚstripÚsplitÚaddÚremoveÚRuntimeErrorÚ
excepthookÚexc_infor   r   r(   ÚdecodeÚ_multiprocessingZ
sem_unlink)ÚfdÚfÚcacheÚliner   r$   Úer   r   r   Úmainl   sJ    



(rI   )r   r3   r   r	   r   rC   Ú r   r   Ú__all__Úobjectr   Z_semaphore_trackerr   r   r   r   rI   r   r   r   r   Ú<module>   s   
J