o
    f                     @   sd  d dg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Zddl	Z	ddl
mZ ddl
mZmZ ddlmZ dZd	Zd
ZdZe Zdd Zdd ZG dd deZG dd dZdd ZG dd deZ		d*ddZdd ZG dd deZ G d d  d e!Z"G d!d" d"e!Z#e#Z$G d#d$ d$e#Z%G d%d& d&e!Z&G d'd( d(e&Z'G d)d de"Z(dS )+Pool
ThreadPool    N   )util)get_contextTimeoutError)waitINITRUNCLOSE	TERMINATEc                 C   s   t t|  S N)listmapargs r   +/usr/lib/python3.10/multiprocessing/pool.pymapstar/      r   c                 C   s   t t| d | d S )Nr   r   )r   	itertoolsstarmapr   r   r   r   starmapstar2   s   r   c                   @      e Zd Zdd Zdd ZdS )RemoteTracebackc                 C   s
   || _ d S r   tb)selfr   r   r   r   __init__:      
zRemoteTraceback.__init__c                 C   s   | j S r   r   r   r   r   r   __str__<   s   zRemoteTraceback.__str__N)__name__
__module____qualname__r   r!   r   r   r   r   r   9   s    r   c                   @   r   )ExceptionWithTracebackc                 C   s0   t t|||}d|}|| _d| | _d S )N z

"""
%s""")	tracebackformat_exceptiontypejoinexcr   )r   r+   r   r   r   r   r   @   s   
zExceptionWithTraceback.__init__c                 C   s   t | j| jffS r   )rebuild_excr+   r   r    r   r   r   
__reduce__E      z!ExceptionWithTraceback.__reduce__N)r"   r#   r$   r   r-   r   r   r   r   r%   ?   s    r%   c                 C   s   t || _| S r   )r   	__cause__)r+   r   r   r   r   r,   H   s   
r,   c                       s0   e Zd ZdZ fddZdd Zdd Z  ZS )MaybeEncodingErrorzVWraps possible unpickleable errors, so they can be
    safely sent through the socket.c                    s.   t || _t || _tt| | j| j d S r   )reprr+   valuesuperr0   r   )r   r+   r2   	__class__r   r   r   T   s   

zMaybeEncodingError.__init__c                 C   s   d| j | jf S )Nz(Error sending result: '%s'. Reason: '%s')r2   r+   r    r   r   r   r!   Y   s   zMaybeEncodingError.__str__c                 C   s   d| j j| f S )Nz<%s: %s>)r5   r"   r    r   r   r   __repr__]   r.   zMaybeEncodingError.__repr__)r"   r#   r$   __doc__r   r!   r6   __classcell__r   r   r4   r   r0   P   s
    r0   r   Fc              
   C   s  |d urt |tr|dkstd||j}| j}t| dr)| j  |j	  |d ur1||  d}|d u s=|r||k rz| }	W n t
tfyR   td Y nw |	d u r]td n|	\}
}}}}zd||i |f}W n" ty } z|r|turt||j}d|f}W Y d }~nd }~ww z	||
||f W n) ty } zt||d }td	|  ||
|d|ff W Y d }~nd }~ww d  }	 }
 } } }}|d7 }|d u s=|r||k s=td
|  d S )Nr   zMaxtasks {!r} is not valid_writerr   z)worker got EOFError or OSError -- exitingzworker got sentinel -- exitingTFz0Possible encoding error while sending result: %szworker exiting after %d tasks)
isinstanceintAssertionErrorformatputgethasattrr9   close_readerEOFErrorOSErrorr   debug	Exception_helper_reraises_exceptionr%   __traceback__r0   )inqueueoutqueueinitializerinitargsmaxtaskswrap_exceptionr>   r?   	completedtaskjobifuncr   kwdsresultewrappedr   r   r   workera   sX   





rX   c                 C   s   | )z@Pickle-able helper function for use by _guarded_task_generation.r   )exr   r   r   rG         rG   c                       s2   e Zd ZdZdd fdd
Z fddZ  ZS )
_PoolCachez
    Class that implements a cache for the Pool class that will notify
    the pool management threads every time the cache is emptied. The
    notification is done by the use of a queue that is provided when
    instantiating the cache.
    Nnotifierc                  s   || _ t j|i | d S r   )r]   r3   r   )r   r]   r   rT   r4   r   r   r      s   z_PoolCache.__init__c                    s$   t  | | s| jd  d S d S r   )r3   __delitem__r]   r>   )r   itemr4   r   r   r^      s   z_PoolCache.__delitem__)r"   r#   r$   r7   r   r^   r8   r   r   r4   r   r[      s    r[   c                   @   s  e Zd ZdZdZedd Z		dLddZej	e
fd	d
Zdd Zdd Zedd Zedd Zdd Zedd Zedd Zdd Zdd Zdi fddZdMdd ZdMd!d"Z		dNd#d$Zd%d& ZdOd(d)ZdOd*d+Zdi ddfd,d-Z		dNd.d/Z		dNd0d1ZedMd2d3Ze d4d5 Z!ed6d7 Z"ed8d9 Z#ed:d; Z$d<d= Z%d>d? Z&d@dA Z'dBdC Z(edDdE Z)e dFdG Z*dHdI Z+dJdK Z,dS )Pr   zS
    Class which supports an async version of applying functions to arguments.
    Tc                 O   s   | j |i |S r   Process)ctxr   rT   r   r   r   ra      s   zPool.ProcessNr   c                 C   s0  g | _ t| _|p
t | _|   t | _| j | _	t
| j	d| _|| _|| _|| _|d u r5t p4d}|dk r=td|d urNt|trJ|dkrNtd|d urZt|sZtd|| _z|   W n! ty   | j D ]}|jd u rx|  qm| j D ]}|  q| w |  }tjtj | j| j| j| j!| j| j | j"| j#| j| j| j| j$|| j	fd| _%d| j%_&t'| j%_| j%(  tjtj)| j| j*| j#| j | jfd| _+d| j+_&t'| j+_| j+(  tjtj,| j#| j-| jfd| _.d| j._&t'| j._| j.(  t/j0| | j1| j| j"| j#| j | j	| j%| j+| j.| jf	d	d
| _2t'| _d S )Nr\   r   z&Number of processes must be at least 1r   z/maxtasksperchild must be a positive int or Nonezinitializer must be a callabletargetr   T   )r   exitpriority)3_poolr	   _stater   _ctx_setup_queuesqueueSimpleQueue
_taskqueue_change_notifierr[   _cache_maxtasksperchild_initializer	_initargsos	cpu_count
ValueErrorr:   r;   callable	TypeError
_processes_repopulate_poolrF   exitcode	terminater*   _get_sentinels	threadingThreadr   _handle_workersra   _inqueue	_outqueue_wrap_exception_worker_handlerdaemonr
   start_handle_tasks
_quick_put_task_handler_handle_results
_quick_get_result_handlerr   Finalize_terminate_pool
_terminate)r   	processesrK   rL   maxtasksperchildcontextp	sentinelsr   r   r   r      s   









zPool.__init__c                 C   sF   | j |kr|d| t| d t| dd d ur!| jd  d S d S d S )Nz&unclosed running multiprocessing pool )sourcern   )rh   ResourceWarninggetattrrn   r>   )r   _warnr
   r   r   r   __del__
  s   

zPool.__del__c              	   C   s0   | j }d|j d|j d| j dt| j d	S )N<.z state=z pool_size=>)r5   r#   r$   rh   lenrg   )r   clsr   r   r   r6     s   zPool.__repr__c                 C   s    | j jg}| jjg}g ||S r   )r   rB   rn   )r   task_queue_sentinelsself_notifier_sentinelsr   r   r   r|     s   

zPool._get_sentinelsc                 C   s   dd | D S )Nc                 S   s   g | ]
}t |d r|jqS )sentinel)r@   r   ).0rX   r   r   r   
<listcomp>  s    z.Pool._get_worker_sentinels.<locals>.<listcomp>r   workersr   r   r   _get_worker_sentinels  s   zPool._get_worker_sentinelsc                 C   sP   d}t tt| D ]}| | }|jdur%td|  |  d}| |= q
|S )zCleanup after any worker processes which have exited due to reaching
        their specified lifetime.  Returns True if any workers were cleaned up.
        FNcleaning up worker %dT)reversedranger   rz   r   rE   r*   )poolcleanedrR   rX   r   r   r   _join_exited_workers!  s   
zPool._join_exited_workersc                 C   s0   |  | j| j| j| j| j| j| j| j| j	| j

S r   )_repopulate_pool_staticri   ra   rx   rg   r   r   rq   rr   rp   r   r    r   r   r   ry   1  s   zPool._repopulate_poolc
              
   C   sf   t |t| D ](}
|| t||||||	fd}|jdd|_d|_|  || t	d qdS )zBring the number of pool processes up to the specified number,
        for use after reaping workers which have exited.
        rc   ra   
PoolWorkerTzadded workerN)
r   r   rX   namereplacer   r   appendr   rE   )rb   ra   r   r   rI   rJ   rK   rL   r   rN   rR   wr   r   r   r   :  s   
zPool._repopulate_pool_staticc
           
      C   s.   t |rt | |||||||||	
 dS dS )zEClean up any exited workers and start replacements for them.
        N)r   r   r   )
rb   ra   r   r   rI   rJ   rK   rL   r   rN   r   r   r   _maintain_poolM  s   
zPool._maintain_poolc                 C   s4   | j  | _| j  | _| jjj| _| jjj| _	d S r   )
ri   rl   r   r   r9   sendr   rB   recvr   r    r   r   r   rj   Y  s   zPool._setup_queuesc                 C   s   | j tkr	tdd S )NzPool not running)rh   r
   ru   r    r   r   r   _check_running_  s   
zPool._check_runningc                 C   s   |  ||| S )zT
        Equivalent of `func(*args, **kwds)`.
        Pool must be running.
        )apply_asyncr?   )r   rS   r   rT   r   r   r   applyc  s   z
Pool.applyc                 C      |  ||t| S )zx
        Apply `func` to each element in `iterable`, collecting the results
        in a list that is returned.
        )
_map_asyncr   r?   r   rS   iterable	chunksizer   r   r   r   j  s   zPool.mapc                 C   r   )z
        Like `map()` method but the elements of the `iterable` are expected to
        be iterables as well and will be unpacked as arguments. Hence
        `func` and (a, b) becomes func(a, b).
        )r   r   r?   r   r   r   r   r   q  s   zPool.starmapc                 C      |  ||t|||S )z=
        Asynchronous version of `starmap()` method.
        )r   r   r   rS   r   r   callbackerror_callbackr   r   r   starmap_asyncy  s   zPool.starmap_asyncc              
   c   sn    zd}t |D ]\}}||||fi fV  qW dS  ty6 } z||d t|fi fV  W Y d}~dS d}~ww )zProvides a generator of tasks for imap and imap_unordered with
        appropriate handling for iterables which throw exceptions during
        iteration.r   N)	enumeraterF   rG   )r   
result_jobrS   r   rR   xrV   r   r   r   _guarded_task_generation  s   $zPool._guarded_task_generationr   c                 C      |    |dkrt| }| j| |j|||jf |S |dk r(td|t	
|||}t| }| j| |jt||jf dd |D S )zP
        Equivalent of `map()` -- can be MUCH slower than `Pool.map()`.
        r   zChunksize must be 1+, not {0:n}c                 s       | ]
}|D ]}|V  qqd S r   r   r   chunkr_   r   r   r   	<genexpr>      zPool.imap.<locals>.<genexpr>)r   IMapIteratorrm   r>   r   _job_set_lengthru   r=   r   
_get_tasksr   r   rS   r   r   rU   task_batchesr   r   r   imap  s4   z	Pool.imapc                 C   r   )zL
        Like `imap()` method but ordering of results is arbitrary.
        r   zChunksize must be 1+, not {0!r}c                 s   r   r   r   r   r   r   r   r     r   z&Pool.imap_unordered.<locals>.<genexpr>)r   IMapUnorderedIteratorrm   r>   r   r   r   ru   r=   r   r   r   r   r   r   r   imap_unordered  s0   zPool.imap_unorderedc                 C   s6   |    t| ||}| j|jd|||fgdf |S )z;
        Asynchronous version of `apply()` method.
        r   N)r   ApplyResultrm   r>   r   )r   rS   r   rT   r   r   rU   r   r   r   r     s   zPool.apply_asyncc                 C   r   )z9
        Asynchronous version of `map()` method.
        )r   r   r   r   r   r   	map_async  s   zPool.map_asyncc           
      C   s   |    t|dst|}|du r%tt|t| jd \}}|r%|d7 }t|dkr-d}t|||}t| |t|||d}	| j	
| |	j||df |	S )zY
        Helper function to implement map, starmap and their async counterparts.
        __len__N   r   r   r   )r   r@   r   divmodr   rg   r   r   	MapResultrm   r>   r   r   )
r   rS   r   mapperr   r   r   extrar   rU   r   r   r   r     s,   
zPool._map_asyncc                 C   s,   t | |d | s|  | r
d S d S )N)timeout)r   emptyr?   )r   change_notifierr   r   r   r   _wait_for_updates  s   zPool._wait_for_updatesc                 C   s   t  }|jtks|r9|jtkr9| |||||||	|
||
 g | ||}| || |jtks|r9|jtks|d  t	
d d S )Nzworker handler exiting)r}   current_threadrh   r
   r   r   r   r   r>   r   rE   )r   cache	taskqueuerb   ra   r   r   rI   rJ   rK   rL   r   rN   r   r   threadcurrent_sentinelsr   r   r   r     s   
	zPool._handle_workersc                 C   st  t  }t| jd D ]z\}}d }zm|D ]D}|jtkr!td  nTz|| W q tyW }	 z$|d d \}
}z||
 	|d|	f W n	 t
yL   Y nw W Y d }	~	qd }	~	ww |rmtd |re|d nd}||d  W d  } }}
q
W d  } }}
 nd  } }}
w td ztd |d  td	 |D ]}|d  qW n ty   td
 Y nw td d S )Nz'task handler found thread._state != RUN   Fzdoing set_length()r   r   ztask handler got sentinelz/task handler sending sentinel to result handlerz(task handler sending sentinel to workersz/task handler got OSError when sending sentinelsztask handler exiting)r}   r   iterr?   rh   r
   r   rE   rF   _setKeyErrorr>   rD   )r   r>   rJ   r   r   r   taskseq
set_lengthrP   rV   rQ   idxr   r   r   r   r     sN   







zPool._handle_tasksc              	   C   s  t  }	 z| }W n ttfy   td Y d S w |jtkr0|jtks*J dtd n*|d u r:td n |\}}}z
|| 	|| W n	 t
yR   Y nw d  } }}q|r|jtkrz| }W n ttfyw   td Y d S w |d u rtd qZ|\}}}z
|| 	|| W n	 t
y   Y nw d  } }}|r|jtksat| drtd ztd	D ]}| j s n|  qW n ttfy   Y nw td
t||j d S )Nr   z.result handler got EOFError/OSError -- exitingzThread not in TERMINATEz,result handler found thread._state=TERMINATEzresult handler got sentinelz&result handler ignoring extra sentinelrB   z"ensuring that outqueue is not full
   z7result handler exiting: len(cache)=%s, thread._state=%s)r}   r   rD   rC   r   rE   rh   r
   r   r   r   r@   r   rB   pollr   )rJ   r?   r   r   rP   rQ   rR   objr   r   r   r   =  sn   













zPool._handle_resultsc                 c   s0    t |}	 tt||}|sd S | |fV  qr   )r   tupler   islice)rS   itsizer   r   r   r   r   y  s   
zPool._get_tasksc                 C   s   t d)Nz:pool objects cannot be passed between processes or pickled)NotImplementedErrorr    r   r   r   r-     s   zPool.__reduce__c                 C   s6   t d | jtkrt| _t| j_| jd  d S d S )Nzclosing pool)r   rE   rh   r
   r   r   rn   r>   r    r   r   r   rA     s   

z
Pool.closec                 C   s   t d t| _|   d S )Nzterminating pool)r   rE   r   rh   r   r    r   r   r   r{     s   
zPool.terminatec                 C   sh   t d | jtkrtd| jttfvrtd| j  | j	  | j
  | jD ]}|  q+d S )Nzjoining poolzPool is still runningzIn unknown state)r   rE   rh   r
   ru   r   r   r   r*   r   r   rg   )r   r   r   r   r   r*     s   






z	Pool.joinc                 C   s\   t d | j  | r(| j r,| j  t	d | r*| j sd S d S d S d S )Nz7removing tasks from inqueue until task handler finishedr   )
r   rE   _rlockacquireis_aliverB   r   r   timesleep)rI   task_handlerr   r   r   r   _help_stuff_finish  s   



"zPool._help_stuff_finishc
                 C   sV  t d t|_|d  t|_t d | ||t| | s,t|	dkr,tdt|_|d  |d  t d t	
 |urH|  |rdt|d drdt d |D ]}
|
jd u rc|
  qXt d t	
 |urs|  t d	 t	
 |ur|  |rt|d drt d
 |D ]}
|
 rt d|
j  |
  qd S d S d S )Nzfinalizing poolz&helping task handler/workers to finishr   z.Cannot have cache with result_hander not alivezjoining worker handlerr{   zterminating workerszjoining task handlerzjoining result handlerzjoining pool workersr   )r   rE   r   rh   r>   r   r   r   r<   r}   r   r*   r@   rz   r{   pid)r   r   rI   rJ   r   r   worker_handlerr   result_handlerr   r   r   r   r   r     sJ   










zPool._terminate_poolc                 C   s   |    | S r   )r   r    r   r   r   	__enter__  s   zPool.__enter__c                 C   s   |    d S r   )r{   )r   exc_typeexc_valexc_tbr   r   r   __exit__  r   zPool.__exit__)NNr   NNr   )NNN)r   )-r"   r#   r$   r7   r   staticmethodra   r   warningswarnr
   r   r6   r|   r   r   ry   r   r   rj   r   r   r   r   r   r   r   r   r   r   r   r   classmethodr   r   r   r   r-   rA   r{   r*   r   r   r  r  r   r   r   r   r      sx    

S

	












-
;


5c                   @   sJ   e Zd Zdd Zdd Zdd Zddd	Zdd
dZdd Ze	e
jZdS )r   c                 C   s>   || _ t | _tt| _|j| _|| _|| _	| | j| j< d S r   )
rg   r}   Event_eventnextjob_counterr   ro   	_callback_error_callback)r   r   r   r   r   r   r   r     s   

zApplyResult.__init__c                 C   s
   | j  S r   )r  is_setr    r   r   r   ready  r   zApplyResult.readyc                 C   s   |   std| | jS )Nz{0!r} not ready)r  ru   r=   _successr    r   r   r   
successful  s   zApplyResult.successfulNc                 C   s   | j | d S r   )r  r   r   r   r   r   r   r     r.   zApplyResult.waitc                 C   s(   |  | |  st| jr| jS | jr   )r   r  r   r  _valuer  r   r   r   r?     s   
zApplyResult.getc                 C   sZ   |\| _ | _| jr| j r| | j | jr| j s| | j | j  | j| j= d | _d S r   )	r  r  r  r  r  setro   r   rg   r   rR   r   r   r   r   r     s   


zApplyResult._setr   )r"   r#   r$   r   r  r  r   r?   r   r	  typesGenericAlias__class_getitem__r   r   r   r   r     s    	

	
r   c                   @   r   )r   c                 C   sj   t j| |||d d| _d g| | _|| _|dkr(d| _| j  | j| j	= d S || t
||  | _d S )Nr   Tr   )r   r   r  r  
_chunksize_number_leftr  r  ro   r   bool)r   r   r   lengthr   r   r   r   r   r     s   

zMapResult.__init__c                 C   s   |  j d8  _ |\}}|r>| jr>|| j|| j |d | j < | j dkr<| jr-| | j | j| j= | j  d | _	d S d S |sI| jrId| _|| _| j dkrf| j
rW| 
| j | j| j= | j  d | _	d S d S )Nr   r   F)r  r  r  r  r  ro   r   r  r  rg   r  )r   rR   success_resultsuccessrU   r   r   r   r   )  s*   









zMapResult._setN)r"   r#   r$   r   r   r   r   r   r   r     s    r   c                   @   s:   e Zd Zdd Zdd ZdddZeZdd	 Zd
d ZdS )r   c                 C   sT   || _ tt | _tt| _|j| _t	
 | _d| _d | _i | _| | j| j< d S )Nr   )rg   r}   	ConditionLock_condr  r  r   ro   collectionsdeque_items_index_length	_unsorted)r   r   r   r   r   r   G  s   

zIMapIterator.__init__c                 C   s   | S r   r   r    r   r   r   __iter__R  s   zIMapIterator.__iter__Nc                 C   s   | j I z| j }W n9 tyD   | j| jkrd | _td | j | z| j }W n tyA   | j| jkr>d | _td t	d w Y nw W d    n1 sOw   Y  |\}}|r\|S |r   )
r#  r&  popleft
IndexErrorr'  r(  rg   StopIterationr   r   )r   r   r_   r   r2   r   r   r   r  U  s0   zIMapIterator.nextc                 C   s   | j \ | j|kr<| j| |  jd7  _| j| jv r6| j| j}| j| |  jd7  _| j| jv s| j   n|| j|< | j| jkrW| j| j	= d | _
W d    d S W d    d S 1 sbw   Y  d S Nr   )r#  r'  r&  r   r)  popnotifyr(  ro   r   rg   r  r   r   r   r   m  s"   


"zIMapIterator._setc                 C   sh   | j ' || _| j| jkr"| j   | j| j= d | _W d    d S W d    d S 1 s-w   Y  d S r   )r#  r(  r'  r0  ro   r   rg   )r   r  r   r   r   r   ~  s   

"zIMapIterator._set_lengthr   )	r"   r#   r$   r   r*  r  __next__r   r   r   r   r   r   r   E  s    
r   c                   @   s   e Zd Zdd ZdS )r   c                 C   s|   | j 1 | j| |  jd7  _| j   | j| jkr,| j| j= d | _W d    d S W d    d S 1 s7w   Y  d S r.  )	r#  r&  r   r'  r0  r(  ro   r   rg   r  r   r   r   r     s   

"zIMapUnorderedIterator._setN)r"   r#   r$   r   r   r   r   r   r     s    r   c                   @   sV   e Zd ZdZedd ZdddZdd	 Zd
d Zedd Z	edd Z
dd ZdS )r   Fc                 O   s   ddl m} ||i |S )Nr   r`   )dummyra   )rb   r   rT   ra   r   r   r   ra     s   zThreadPool.ProcessNr   c                 C   s   t | ||| d S r   )r   r   )r   r   rK   rL   r   r   r   r     s   zThreadPool.__init__c                 C   s,   t  | _t  | _| jj| _| jj| _d S r   )rk   rl   r   r   r>   r   r?   r   r    r   r   r   rj     s   


zThreadPool._setup_queuesc                 C   s
   | j jgS r   )rn   rB   r    r   r   r   r|     r   zThreadPool._get_sentinelsc                 C   s   g S r   r   r   r   r   r   r     rZ   z ThreadPool._get_worker_sentinelsc                 C   sB   z	 | j dd q tjy   Y nw t|D ]}| d  qd S )NTF)block)r?   rk   Emptyr   r>   )rI   r   r   rR   r   r   r   r     s   zThreadPool._help_stuff_finishc                 C   s   t | d S r   )r   r   )r   r   r   r   r   r   r   r     s   zThreadPool._wait_for_updates)NNr   )r"   r#   r$   r   r  ra   r   rj   r|   r   r   r   r   r   r   r   r     s    




)Nr   NF))__all__r$  r   rs   rk   r}   r   r'   r  r  r&   r   r   r   
connectionr   r	   r
   r   r   countr  r   r   rF   r   r%   r,   r0   rX   rG   dictr[   objectr   r   AsyncResultr   r   r   r   r   r   r   r   <module>   sP   		
-    @++E