
    \d'                         d Z ddlmZmZ ddlmZ ddlmZ ddl	m
Z
mZ ddlmZ ddlmZ ddlmZ  e            Z G d	 d
          ZdS )z
twisted.python.threadpool: a pool of threads to which we dispatch tasks.

In most cases you can just use C{reactor.callInThread} and friends
instead of creating a thread pool directly.
    )Threadcurrent_thread)List)pool)contextlog)
deprecated)Failure)Versionc                   >   e Zd ZdZdZdZdZdZdZe	Z
 e  e edddd	          d
          e                    Z ee          ZddZed             Zed             Zed             Zed             ZeZd Zd Zd Zd Zd Zd Zd Zd Zd Z ddZ!d Z"dS )
ThreadPoola  
    This class (hopefully) generalizes the functionality of a pool of threads
    to which work can be dispatched.

    L{callInThread} and L{stop} should only be called from a single thread.

    @ivar started: Whether or not the thread pool is currently running.
    @type started: L{bool}

    @ivar threads: List of workers currently running in this thread pool.
    @type threads: L{list}

    @ivar _pool: A hook for testing.
    @type _pool: callable compatible with L{_pool}
          FNTwisted      r   zthreading.current_thread)versionreplacementc                      |dk    s
J d            ||k    s
J d            | _         | _        | _        g  _         fd} fd}                     ||           _        dS )ac  
        Create a new threadpool.

        @param minthreads: minimum number of threads in the pool
        @type minthreads: L{int}

        @param maxthreads: maximum number of threads in the pool
        @type maxthreads: L{int}

        @param name: The name to give this threadpool; visible in log messages.
        @type name: native L{str}
        r   minimum is negativeminimum is greater than maximumc                  ~     j         | d                                i|}j                            |           |S )Nname)threadFactory_generateNamethreadsappend)akwthreadselfs      9lib/python3.11/site-packages/twisted/python/threadpool.pytrackingThreadFactoryz2ThreadPool.__init__.<locals>.trackingThreadFactoryL   sS    'T'++--13 F L'''M    c                  $     j         sdS  j        S )Nr   )startedmaxr!   s   r"   currentLimitz)ThreadPool.__init__.<locals>.currentLimitS   s    < q8Or$   N)minr'   r   r   _pool_team)r!   
minthreads
maxthreadsr   r#   r)   s   `     r"   __init__zThreadPool.__init__8   s     Q 5Z''')J'''	%'	 	 	 	 		 	 	 	 	
 ZZ.CDD


r$   c                 R    | j                                         }|j        |j        z   S )a  
        For legacy compatibility purposes, return a total number of workers.

        @return: the current number of workers, both idle and busy (but not
            those that have been quit by L{ThreadPool.adjustPoolsize})
        @rtype: L{int}
        )r,   
statisticsidleWorkerCountbusyWorkerCount)r!   statss     r"   workerszThreadPool.workersZ   s(     
%%''$u'<<<r$   c                 F    dg| j                                         j        z  S )z
        For legacy compatibility purposes, return the number of busy workers as
        expressed by a list the length of that number.

        @return: the number of workers currently processing a work item.
        @rtype: L{list} of L{None}
        N)r,   r1   r3   r(   s    r"   workingzThreadPool.workingf   s"     v
--//???r$   c                 F    dg| j                                         j        z  S )a,  
        For legacy compatibility purposes, return the number of idle workers as
        expressed by a list the length of that number.

        @return: the number of workers currently alive (with an allocated
            thread) but waiting for new work.
        @rtype: L{list} of L{None}
        N)r,   r1   r2   r(   s    r"   waiterszThreadPool.waitersq   s"     v
--//???r$   c                 6      G  fdd          } |            S )z
        For legacy compatibility purposes, return an object with a C{qsize}
        method that indicates the amount of work not yet allocated to a worker.

        @return: an object with a C{qsize} method.
        c                       e Zd Z fdZdS )$ThreadPool._queue.<locals>.NotAQueuec                 @    j                                         j        S )a  
                Pretend to be a Python threading Queue and return the
                number of as-yet-unconsumed tasks.

                @return: the amount of backlogged work not yet dispatched to a
                    worker.
                @rtype: L{int}
                )r,   r1   backloggedWorkCount)qr!   s    r"   qsizez*ThreadPool._queue.<locals>.NotAQueue.qsize   s     z,,..BBr$   N)__name__
__module____qualname__r@   r(   s   r"   	NotAQueuer<      s5        	C 	C 	C 	C 	C 	C 	Cr$   rD    )r!   rD   s   ` r"   _queuezThreadPool._queue}   sM    
	C 
	C 
	C 
	C 
	C 
	C 
	C 
	C 
	C 
	C y{{r$   c                     d| _         d| _        |                                  | j                                        j        }|r| j                            |           dS dS )z'
        Start the threadpool.
        FTN)joinedr&   adjustPoolsizer,   r1   r>   grow)r!   backlogs     r"   startzThreadPool.start   sf     *''))= 	%JOOG$$$$$	% 	%r$   c                 :    | j                             d           dS )z
        Increase the number of available workers for the thread pool by 1, up
        to the maximum allowed by L{ThreadPool.max}.
        r   N)r,   rJ   r(   s    r"   startAWorkerzThreadPool.startAWorker   s    
 	
r$   c                 D    d| j         pt          |            d| j         S )z
        Generate a name for a new pool thread.

        @return: A distinctive name for the thread.
        @rtype: native L{str}
        zPoolThread--)r   idr5   r(   s    r"   r   zThreadPool._generateName   s*     DTY2"T((CCT\CCCr$   c                 :    | j                             d           dS )zn
        Decrease the number of available workers by 1, by quitting one as soon
        as it's idle.
        r   N)r,   shrinkr(   s    r"   stopAWorkerzThreadPool.stopAWorker   s     
 	
!r$   c                 t    t          | d|           t                              | | j        | j                   d S )N__dict__)setattrr   r/   r*   r'   r!   states     r"   __setstate__zThreadPool.__setstate__   s6    j%(((D$(DH55555r$   c                 2    i }| j         |d<   | j        |d<   |S )Nr*   r'   )r*   r'   rX   s     r"   __getstate__zThreadPool.__getstate__   s"    xexer$   c                 *     | j         d|g|R i | dS )a   
        Call a callable object in a separate thread.

        @param func: callable object to be called in separate thread

        @param args: positional arguments to be passed to C{func}

        @param kw: keyword args to be passed to C{func}
        N)callInThreadWithCallback)r!   funcargsr   s       r"   callInThreadzThreadPool.callInThread   s/     	&%dD>4>>>2>>>>>r$   c                     | j         rdS t          j                                        j        d         fdfd_        |_        | j                                       dS )a$  
        Call a callable object in a separate thread and call C{onResult} with
        the return value, or a L{twisted.python.failure.Failure} if the
        callable raises an exception.

        The callable is allowed to block, but the C{onResult} function must not
        block and should perform as little work as possible.

        A typical action for C{onResult} for a threadpool used with a Twisted
        reactor would be to schedule a L{twisted.internet.defer.Deferred} to
        fire in the main reactor thread using C{.callFromThread}.  Note that
        C{onResult} is called inside the separate thread, not inside the
        reactor thread.

        @param onResult: a callable with the signature C{(success, result)}.
            If the callable returns normally, C{onResult} is called with
            C{(True, result)} where C{result} is the return value of the
            callable.  If the callable throws an exception, C{onResult} is
            called with C{(False, failure)}.

            Optionally, C{onResult} may be L{None}, in which case it is not
            called at all.

        @param func: callable object to be called in separate thread

        @param args: positional arguments to be passed to C{func}

        @param kw: keyword arguments to be passed to C{func}
        Nc                     	                                  } d}n # t          $ r t                      } d}Y nw xY wd _         j                            ||            d _        d S |st	          j        |            d S d S )NTF)theWorkBaseExceptionr
   onResultr   err)resultok	inContexts     r"   rk   z6ThreadPool.callInThreadWithCallback.<locals>.inContext   s    "**,,      !%I!-""2v...%)	"""     s    77c                  0    t          j        g R i S )N)r   call)r`   ctxr_   r   s   r"   <lambda>z5ThreadPool.callInThreadWithCallback.<locals>.<lambda>  s2    GL%
%
 %
 %
 "%
 %
 r$   )	rH   r   theContextTrackercurrentContextcontextsre   rg   r,   do)r!   rg   r_   r`   r   rn   rk   s     ```@@r"   r^   z#ThreadPool.callInThreadWithCallback   s    < ; 	F'6688A"E	  	  	  	  	 $
 
 
 
 
 
 
	 &	
i     r$   c                     d| _         d| _        | j                                         | j        D ]}|                                 dS )z9
        Shutdown the threads in the threadpool.
        TFN)rH   r&   r,   quitr   join)r!   r    s     r"   stopzThreadPool.stop  sN     
l 	 	FKKMMMM	 	r$   c                 x   || j         }|| j        }|dk    s
J d            ||k    s
J d            || _         || _        | j        sdS | j        | j        k    r'| j                            | j        | j        z
             | j        | j         k     r)| j                            | j         | j        z
             dS dS )z
        Adjust the number of available threads by setting C{min} and C{max} to
        new values.

        @param minthreads: The new value for L{ThreadPool.min}.

        @param maxthreads: The new value for L{ThreadPool.max}.
        Nr   r   r   )r*   r'   r&   r5   r,   rS   rJ   )r!   r-   r.   s      r"   rI   zThreadPool.adjustPoolsize  s     JJQ 5Z''')J'''| 	F <$(""JdlTX5666<$(""JOODHt|344444 #"r$   c                     t          j        d| j                    t          j        d| j                    t          j        d| j                    dS )zw
        Dump some plain-text informational messages to the log about the state
        of this L{ThreadPool}.
        z	waiters: z	workers: ztotal: N)r   msgr9   r7   r   r(   s    r"   	dumpStatszThreadPool.dumpStats2  s[    
 	*DL**+++*DL**+++($,(()))))r$   )r   r   N)NN)#rA   rB   rC   __doc__r*   r'   rH   r&   r   r   r   staticmethodr	   r   r   currentThreadr+   r/   propertyr5   r7   r9   rF   r?   rL   rN   r   rT   rZ   r\   ra   r^   rw   rI   r{   rE   r$   r"   r   r      s          C
CFGDM L	


GIr1a002	
 	
 	
 	 	 M LE E  E  E  ED 	= 	= X	= @ @ X@ 	@ 	@ X	@   X, 	A
% 
% 
%  D D D  6 6 6  
? 
? 
?9! 9! 9!v  5 5 5 5:* * * * *r$   r   N)r|   	threadingr   r   typingr   twisted._threadsr   r+   twisted.pythonr   r   twisted.python.deprecater	   twisted.python.failurer
   twisted.python.versionsr   object
WorkerStopr   rE   r$   r"   <module>r      s   
  - , , , , , , ,       * * * * * * ' ' ' ' ' ' ' ' / / / / / / * * * * * * + + + + + +VXX
a* a* a* a* a* a* a* a* a* a*r$   