o
    éT•j  ã                   @   s²   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gZ
ejdkr<e
dg7 Z
G d	d„ deƒZne
d
g7 Z
G dd
„ d
eƒZG dd„ deƒZeƒ ZejZdS )é    Né   )Úprocess)Ú	reduction)ÚutilÚstopÚwin32Ú	DupSocketc                   @   ó    e Zd ZdZdd„ Zdd„ ZdS )r   zPicklable wrapper for a socket.c                    s(   |  ¡ ‰ ‡ fdd„}t |ˆ j¡| _d S )Nc                    s   ˆ   |¡}|  |¡ d S ©N)ÚshareÚ
send_bytes)ÚconnÚpidr   ©Únew_sock© ú6/usr/lib/python3.10/multiprocessing/resource_sharer.pyÚsend   s   
z DupSocket.__init__.<locals>.send)ÚdupÚ_resource_sharerÚregisterÚcloseÚ_id)ÚselfÚsockr   r   r   r   Ú__init__   s   zDupSocket.__init__c                 C   sB   t  | j¡�}| ¡ }t |¡W  d  ƒ S 1 sw   Y  dS )z1Get the socket.  This should only be called once.N)r   Úget_connectionr   Ú
recv_bytesÚsocketÚ	fromshare)r   r   r   r   r   r   Údetach$   s   $þzDupSocket.detachN©Ú__name__Ú
__module__Ú__qualname__Ú__doc__r   r    r   r   r   r   r      s    ÚDupFdc                   @   r	   )r&   z-Wrapper for fd which can be used at any time.c                    s4   t  |¡‰ ‡ fdd„}‡ fdd„}t ||¡| _d S )Nc                    s   t  | ˆ |¡ d S r
   )r   Úsend_handle)r   r   ©Únew_fdr   r   r   1   s   zDupFd.__init__.<locals>.sendc                      s   t  ˆ ¡ d S r
   )Úosr   r   r(   r   r   r   3   s   zDupFd.__init__.<locals>.close)r*   r   r   r   r   )r   Úfdr   r   r   r(   r   r   /   s   
zDupFd.__init__c                 C   s:   t  | j¡�}t |¡W  d  ƒ S 1 sw   Y  dS )z-Get the fd.  This should only be called once.N)r   r   r   r   Úrecv_handle)r   r   r   r   r   r    7   s   $ÿzDupFd.detachNr!   r   r   r   r   r&   -   s    c                   @   sN   e Zd ZdZdd„ Zdd„ Zedd„ ƒZdd	d
„Zdd„ Z	dd„ Z
dd„ ZdS )Ú_ResourceSharerz.Manager for resources using background thread.c                 C   s:   d| _ i | _t ¡ | _d | _d | _d | _t 	| t
j¡ d S )Nr   )Ú_keyÚ_cacheÚ	threadingÚLockÚ_lockÚ	_listenerÚ_addressÚ_threadr   Úregister_after_forkr-   Ú
_afterfork)r   r   r   r   r   ?   s   
z_ResourceSharer.__init__c                 C   sf   | j �& | jdu r|  ¡  |  jd7  _||f| j| j< | j| jfW  d  ƒ S 1 s,w   Y  dS )z+Register resource, returning an identifier.Nr   )r2   r4   Ú_startr.   r/   )r   r   r   r   r   r   r   H   s   

$ûz_ResourceSharer.registerc                 C   s<   ddl m} | \}}||t ¡ jd�}| |t ¡ f¡ |S )z<Return connection from which to receive identified resource.r   ©ÚClient©Úauthkey)Ú
connectionr:   r   Úcurrent_processr<   r   r*   Úgetpid)Úidentr:   ÚaddressÚkeyÚcr   r   r   r   Q   s
   z_ResourceSharer.get_connectionNc                 C   sÜ   ddl m} | j�[ | jdur\|| jt ¡ jd�}| d¡ | ¡  | j	 
|¡ | j	 ¡ r2t d¡ | j ¡  d| _	d| _d| _| j ¡ D ]	\}\}}|ƒ  qE| j ¡  W d  ƒ dS W d  ƒ dS 1 sgw   Y  dS )z:Stop the background thread and clear registered resources.r   r9   Nr;   z._ResourceSharer thread did not stop when asked)r=   r:   r2   r4   r   r>   r<   r   r   r5   ÚjoinÚis_aliver   Úsub_warningr3   r/   ÚitemsÚclear)r   Útimeoutr:   rC   rB   r   r   r   r   r   r   Z   s*   
ÿ



ð"ÿz_ResourceSharer.stopc                 C   s\   | j  ¡ D ]	\}\}}|ƒ  q| j  ¡  | j ¡  | jd ur#| j ¡  d | _d | _d | _d S r
   )	r/   rG   rH   r2   Ú_at_fork_reinitr3   r   r4   r5   )r   rB   r   r   r   r   r   r7   o   s   




z_ResourceSharer._afterforkc                 C   sj   ddl m} | jd u sJ dƒ‚t d¡ |t ¡ jd�| _| jj| _	t
j| jd�}d|_| ¡  || _d S )Nr   )ÚListenerzAlready have Listenerz0starting listener and thread for sending handlesr;   )ÚtargetT)r=   rK   r3   r   Údebugr   r>   r<   rA   r4   r0   ÚThreadÚ_serveÚdaemonÚstartr5   )r   rK   Útr   r   r   r8   z   s   


z_ResourceSharer._startc                 C   sÈ   t tdƒrt tjt ¡ ¡ 	 zD| j ¡ �5}| ¡ }|d u r(	 W d   ƒ W d S |\}}| j 	|¡\}}z
|||ƒ W |ƒ  n|ƒ  w W d   ƒ n1 sMw   Y  W n   t
 ¡ sbtjt ¡ Ž  Y q)NÚpthread_sigmask)ÚhasattrÚsignalrS   Ú	SIG_BLOCKÚvalid_signalsr3   ÚacceptÚrecvr/   Úpopr   Ú
is_exitingÚsysÚ
excepthookÚexc_info)r   r   ÚmsgrB   Údestination_pidr   r   r   r   r   rO   …   s*   
ý÷€
€òz_ResourceSharer._server
   )r"   r#   r$   r%   r   r   Ústaticmethodr   r   r7   r8   rO   r   r   r   r   r-   =   s    		

r-   )r*   rU   r   r\   r0   Ú r   Úcontextr   r   Ú__all__ÚplatformÚobjectr   r&   r-   r   r   r   r   r   r   Ú<module>   s"   



\
