3
,6`
$                 @   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
mZ ddddd	gZe	jd
kpeedoeedoeejdZG dd dejZejZd5dd	Ze	jd
kredddg7 Zd dlZd6ddZdd Zdd Zdd ZG dd deZnHedddg7 Zd dlZe	jdkZdd Zdd Zdd Zd d Zd!d Zd"d# Z G d$d% d%Z!ee"e! j#e  d&d' Z$ee"e%j&e$ ee"e'j(e$ d(d) Z)d*d+ Z*eej+e) e	jd
krd,d- Z,d.d/ Z-eeje, nd0d- Z,d1d/ Z-eeje, G d2d3 d3ed4Z.dS )7    )ABCMetaabstractmethodN   )contextsend_handlerecv_handleForkingPicklerregisterdumpwin32ZCMSG_LEN
SCM_RIGHTSsendmsgc                   sJ   e Zd ZdZi ZejZ fddZe	dd Z
e	d	ddZejZ  ZS )
r   z)Pickler subclass used by multiprocessing.c                s*   t  j|  | jj | _| jj| j d S )N)super__init___copyreg_dispatch_tablecopydispatch_tableupdate_extra_reducers)selfargs)	__class__ //usr/lib/python3.6/multiprocessing/reduction.pyr   &   s    zForkingPickler.__init__c             C   s   || j |< dS )z&Register a reduce function for a type.N)r   )clstypereducer   r   r   r	   +   s    zForkingPickler.registerNc             C   s    t j }| ||j| |j S )N)ioBytesIOr
   	getbuffer)r   objprotocolZbufr   r   r   dumps0   s    zForkingPickler.dumps)N)__name__
__module____qualname____doc__r   copyregr   r   r   classmethodr	   r"   pickleloads__classcell__r   r   )r   r   r   !   s   c             C   s   t ||j|  dS )z3Replacement for pickle.dump() using ForkingPickler.N)r   r
   )r    filer!   r   r   r   r
   :   s    	DupHandle	duplicatesteal_handleFc             C   s*   |dkrt j }t jt j | |d|t jS )z<Duplicate a handle.  (target_process is a handle not a pid!)Nr   )_winapiGetCurrentProcessDuplicateHandleDUPLICATE_SAME_ACCESS)handleZtarget_processZinheritabler   r   r   r.   G   s
    
c             C   sB   t jt jd| }z t j||t j ddt jt jB S t j| X dS )z5Steal a handle from process identified by source_pid.Fr   N)r0   OpenProcessPROCESS_DUP_HANDLEr2   r1   r3   DUPLICATE_CLOSE_SOURCECloseHandle)Z
source_pidr4   Zsource_process_handler   r   r   r/   O   s    
c             C   s   t |tj|}| j| dS )z&Send a handle over a local connection.N)r-   r0   r3   send)connr4   destination_pidZdhr   r   r   r   [   s    c             C   s   | j  j S )z)Receive a handle over a local connection.)recvdetach)r:   r   r   r   r   `   s    c               @   s"   e Zd ZdZdddZdd ZdS )r-   zPicklable wrapper for a handle.Nc             C   s\   |d krt j }tjtjd|}ztjtj |||dd| _W d tj| X || _	|| _
d S )NFr   )osgetpidr0   r5   r6   r2   r1   _handler8   _access_pid)r   r4   accesspidprocr   r   r   r   f   s    zDupHandle.__init__c             C   sV   | j tj kr| jS tjtjd| j }ztj|| jtj | j	dtj
S tj| X dS )z1Get the handle.  This should only be called once.FN)rB   r>   r?   r@   r0   r5   r6   r2   r1   rA   r7   r8   )r   rE   r   r   r   r=   u   s    
zDupHandle.detach)N)r#   r$   r%   r&   r   r=   r   r   r   r   r-   d   s   
DupFdsendfdsrecvfdsdarwinc             C   sV   t j d|}tt|d g}| j|gtjtj|fg trR| jddkrRt	ddS )z,Send an array of fds over an AF_UNIX socket.i   r      Az%did not receive acknowledgement of fdN)
arraybyteslenr   socket
SOL_SOCKETr   ACKNOWLEDGEr<   RuntimeError)sockZfdsmsgr   r   r   rG      s
    c             C   s   t j d}|j| }| jdtj|\}}}}| r>| r>tytrN| jd t|dkrjt	dt| |d \}}	}
|tj
kr|	tjkrt|
|j dkrt|j|
 t|d |d kstt|S W n ttfk
r   Y nX t	ddS )	z/Receive an array of fds over an AF_UNIX socket.rJ   r   rL   zreceived %d items of ancdatar   rK   zInvalid data receivedN)rM   itemsizeZrecvmsgrP   Z
CMSG_SPACEEOFErrorrR   r9   rO   rS   rQ   r   
ValueErrorZ	frombytesAssertionErrorlist
IndexError)rT   sizeaZ
bytes_sizerU   ZancdataflagsZaddrZ
cmsg_levelZ	cmsg_typeZ	cmsg_datar   r   r   rH      s,    





c          
   C   s2   t j| j t jt j}t||g W dQ R X dS )z&Send a handle over a local connection.N)rP   fromfdfilenoAF_UNIXSOCK_STREAMrG   )r:   r4   r;   sr   r   r   r      s    c          
   C   s0   t j| j t jt j}t|dd S Q R X dS )z)Receive a handle over a local connection.r   r   N)rP   r_   r`   ra   rb   rH   )r:   rc   r   r   r   r      s    c             C   sF   t j }|dk	r |j|j| S tr:ddlm} |j| S tddS )zReturn a wrapper for an fd.Nr   )resource_sharerz&SCM_RIGHTS appears not to be available)r   Zget_spawning_popenrF   Zduplicate_for_childHAVE_SEND_HANDLE rd   rX   )fdZ	popen_objrd   r   r   r   rF      s    
c             C   s2   | j d krt| j| jjffS t| j | jjffS d S )N)__self__getattrr   __func__r#   )mr   r   r   _reduce_method   s    
rl   c               @   s   e Zd Zdd ZdS )_Cc             C   s   d S )Nr   )r   r   r   r   f   s    z_C.fN)r#   r$   r%   rn   r   r   r   r   rm      s   rm   c             C   s   t | j| jffS )N)ri   __objclass__r#   )rk   r   r   r   _reduce_method_descriptor   s    rp   c             C   s   t | j| j| jpi ffS )N)_rebuild_partialfuncr   keywords)pr   r   r   _reduce_partial   s    ru   c             C   s   t j| f||S )N)	functoolspartial)rr   r   rs   r   r   r   rq      s    rq   c             C   s   ddl m} t|| ffS )Nr   )	DupSocket)rd   rx   _rebuild_socket)rc   rx   r   r   r   _reduce_socket   s    rz   c             C   s   | j  S )N)r=   )Zdsr   r   r   ry      s    ry   c             C   s"   t | j }t|| j| j| jffS )N)rF   r`   ry   familyr   proto)rc   dfr   r   r   rz      s    c             C   s   | j  }tj||||dS )N)r`   )r=   rP   )r}   r{   r   r|   rg   r   r   r   ry      s    c               @   sd   e Zd ZdZeZeZeZeZeZe	j
dkr8eZeZeZneZeZeZeZeZeZeZeZdd ZdS )AbstractReducerzAbstract base class for use in implementing a Reduction class
    suitable for use in replacing the standard reduction mechanism
    used in multiprocessing.r   c             G   sN   t tt jt t ttjt t ttj	t t t
jt t tjt d S )N)r	   r   rm   rn   rl   rZ   appendrp   int__add__rv   rw   ru   rP   rz   )r   r   r   r   r   r     s
    zAbstractReducer.__init__N)r#   r$   r%   r&   r   r	   r
   r   r   sysplatformr/   r.   r-   rG   rH   rF   rl   rp   rq   rz   ry   r   r   r   r   r   r~      s&   
r~   )	metaclass)N)NF)/abcr   r   r'   rv   r   r>   r)   rP   r   rf   r   __all__r   hasattrre   ZPicklerr   r	   r
   r0   r.   r/   r   r   objectr-   rM   rR   rG   rH   rF   rl   rm   r   rn   rp   rZ   r   r   r   ru   rq   rw   rz   ry   r~   r   r   r   r   <module>
   sb   




#
