a
    If(%                     @   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Zddl	m
Z
 g d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d8ddZejdk reg d7 Zd dlZd9ddddZdd Zdd Zdd ZG dd deZnFeg d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/d0 Z+d1d2 Z,eeje+ nd3d0 Z+d4d2 Z,eeje+ G d5d6 d6ed7Z-dS ):    )ABCMetaN   )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 d S N)super__init___copyreg_dispatch_tablecopydispatch_tableupdate_extra_reducersselfargs	__class__ *lib/python3.9/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  }| ||| | S r   )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   
r   c                 C   s   t |||  dS )z3Replacement for pickle.dump() using ForkingPickler.N)r   r	   )r"   filer#   r   r   r   r	   :   s    r	   )	DupHandle	duplicatesteal_handleF)source_processc                C   s6   t  }|du r|}|du r |}t || |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inheritabler2   Zcurrent_processr   r   r   r0   G   s    r0   c              	   C   sN   t t jd| }z,t ||t  ddt jt jB W t | S t | 0 dS )z5Steal a handle from process identified by source_pid.Fr   N)r3   OpenProcessPROCESS_DUP_HANDLEr5   r4   r6   DUPLICATE_CLOSE_SOURCECloseHandle)Z
source_pidr7   Zsource_process_handler   r   r   r1   S   s    


r1   c                 C   s   t |tj|}| | dS z&Send a handle over a local connection.N)r/   r3   r6   send)connr7   destination_pidZdhr   r   r   r   _   s    r   c                 C   s   |    S ))Receive a handle over a local connection.)recvdetach)r>   r   r   r   r   d   s    r   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   sf   |d u rt  }ttjd|}z(tt |||dd| _W t| nt| 0 || _	|| _
d S )NFr   )osgetpidr3   r8   r9   r5   r4   _handler;   _access_pid)r   r7   accesspidprocr   r   r   r   j   s    
zDupHandle.__init__c              	   C   sb   | j t kr| jS ttjd| j }z*t|| jt | j	dtj
W t| S t| 0 dS )z1Get the handle.  This should only be called once.FN)rG   rC   rD   rE   r3   r8   r9   r5   r4   rF   r:   r;   )r   rJ   r   r   r   rB   y   s    


zDupHandle.detach)N)r%   r&   r'   r(   r   rB   r   r   r   r   r/   h   s   
r/   )DupFdsendfdsrecvfdsdarwinc                 C   sV   t  d|}tt|d g}| |gtjtj|fg trR| 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   ACKNOWLEDGErA   RuntimeError)sockZfdsmsgr   r   r   rL      s
    rL   c              	   C   s  t  d}|j| }| dt|\}}}}|s:|s:tztrJ| d t|dkrft	dt| |d \}}	}
|tj
kr|	tjkrt|
|j dkrt||
 t|d |d krtdt||d t|W S W n ttfy   Y n0 t	dd	S )
z/Receive an array of fds over an AF_UNIX socket.rO   r   rQ   zreceived %d items of ancdatar   rP   z Len is {0:n} but msg[0] is {1!r}zInvalid data receivedN)rR   itemsizeZrecvmsgrU   Z
CMSG_SPACEEOFErrorrW   r=   rT   rX   rV   r   
ValueErrorZ	frombytesAssertionErrorformatlist
IndexError)rY   sizeaZ
bytes_sizerZ   ZancdataflagsZaddrZ
cmsg_levelZ	cmsg_typeZ	cmsg_datar   r   r   rM      s:    




rM   c                 C   sF   t |  t jt j}t||g W d   n1 s80    Y  dS r<   )rU   fromfdfilenoAF_UNIXSOCK_STREAMrL   )r>   r7   r?   sr   r   r   r      s    c                 C   sH   t |  t jt j}t|dd W  d   S 1 s:0    Y  dS )r@   r   r   N)rU   re   rf   rg   rh   rM   )r>   ri   r   r   r   r      s    c                 C   sF   t  }|dur ||| S tr:ddlm} || 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_popenrK   Zduplicate_for_childHAVE_SEND_HANDLE rj   r]   )fdZ	popen_objrj   r   r   r   rK      s    
rK   c                 C   s2   | j d u rt| j| jjffS t| j | jjffS d S r   )__self__getattrr   __func__r%   mr   r   r   _reduce_method   s    
rs   c                   @   s   e Zd Zdd ZdS )_Cc                 C   s   d S r   r   )r   r   r   r   f   s    z_C.fN)r%   r&   r'   ru   r   r   r   r   rt      s   rt   c                 C   s   t | j| jffS r   )ro   __objclass__r%   rq   r   r   r   _reduce_method_descriptor   s    rw   c                 C   s   t | j| j| jpi ffS r   )_rebuild_partialfuncr   keywords)pr   r   r   _reduce_partial   s    r|   c                 C   s   t j| g|R i |S r   )	functoolspartial)ry   r   rz   r   r   r   rx      s    rx   c                 C   s   ddl m} t|| ffS )Nr   )	DupSocket)rj   r   _rebuild_socket)ri   r   r   r   r   _reduce_socket   s    r   c                 C   s   |   S r   )rB   )Zdsr   r   r   r      s    r   c                 C   s"   t |  }t|| j| j| jffS r   )rK   rf   r   familyr   proto)ri   dfr   r   r   r      s    c                 C   s   |   }tj||||dS )N)rf   )rB   rU   )r   r   r   r   rm   r   r   r   r      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 r   )r   r   rt   ru   rs   r`   appendrw   int__add__r}   r~   r|   rU   r   r   r   r   r   r     s
    zAbstractReducer.__init__N)r%   r&   r'   r(   r   r   r	   r   r   sysplatformr1   r0   r/   rL   rM   rK   rs   rw   rx   r   r   r   r   r   r   r   r      s&   
r   )	metaclass)N)NF).abcr   r)   r}   r   rC   r+   rU   r   rl   r   __all__r   hasattrrk   ZPicklerr   r   r	   r3   r0   r1   r   r   objectr/   rR   rW   rL   rM   rK   rs   rt   r   ru   rw   r`   r   r   r   r|   rx   r~   r   r   r   r   r   r   r   <module>
   sj   


	
#
