
    Ϫf                        d Z ddlmZ ddlZddlmZmZ ddlmZ ddl	m
Z
 ddlmZ ddlmZ dd	lmZ  ed
      Z ed      Z	 	 	 	 	 	 	 	 	 	 	 	 ddZd Zd Zd Zd Zg dZy)zY
Extended thread dispatching support.

For basic support see reactor threading API docs.
    )annotationsN)CallableTypeVar)	ParamSpec)defer)IReactorFromThreads)failure)
ThreadPool_P_Rc                n     t        j                         d fd} |j                  ||g|i | S )a3  
    Call the function C{f} using a thread from the given threadpool and return
    the result as a Deferred.

    This function is only used by client code which is maintaining its own
    threadpool.  To run a function in the reactor's threadpool, use
    C{deferToThread}.

    @param reactor: The reactor in whose main thread the Deferred will be
        invoked.

    @param threadpool: An object which supports the C{callInThreadWithCallback}
        method of C{twisted.python.threadpool.ThreadPool}.

    @param f: The function to call.
    @param args: positional arguments to pass to f.
    @param kwargs: keyword arguments to pass to f.

    @return: A Deferred which fires a callback with the result of f, or an
        errback with a L{twisted.python.failure.Failure} if f throws an
        exception.
    c                |    | rj                  j                  |       y j                  j                  |       y N)callFromThreadcallbackerrback)successresultdreactors     :/usr/lib/python3/dist-packages/twisted/internet/threads.pyonResultz#deferToThreadPool.<locals>.onResult9   s.    ""1::v6""199f5    )r   boolr   z_R | BaseExceptionreturnNone)r   DeferredcallInThreadWithCallback)r   
threadpoolfargskwargsr   r   s   `     @r   deferToThreadPoolr#      s9    : "NN,A6 (J''!EdEfEHr   c                L    ddl m} t        ||j                         | g|i |S )at  
    Run a function in a thread and return the result as a Deferred.

    @param f: The function to call.
    @param args: positional arguments to pass to f.
    @param kwargs: keyword arguments to pass to f.

    @return: A Deferred which fires a callback with the result of f,
    or an errback with a L{twisted.python.failure.Failure} if f throws
    an exception.
    r   r   )twisted.internetr   r#   getThreadPool)r    r!   r"   r   s       r   deferToThreadr(   D   s)     )Wg&;&;&=qR4R6RRr   c                *    | D ]  \  }}} ||i |  y)z"
    Run a list of functions.
    N )	tupleListr    r!   r"   s       r   _runMultipler,   U   s&     % 4	46r   c                <    ddl m} |j                  t        |        y)z
    Run a list of functions in the same thread.

    tupleList should be a list of (function, argsList, kwargsDict) tuples.
    r   r%   N)r&   r   callInThreadr,   )r+   r   s     r   callMultipleInThreadr/   ]   s     )y1r   c                    t        j                          fd}| j                  |       j                         }t        |t        j
                        r|j                          |S )a  
    Run a function in the reactor from a thread, and wait for the result
    synchronously.  If the function returns a L{Deferred}, wait for its
    result and return that.

    @param reactor: The L{IReactorThreads} provider which will be used to
        schedule the function call.
    @param f: the callable to run in the reactor thread
    @type f: any callable.
    @param a: the arguments to pass to C{f}.
    @param kw: the keyword arguments to pass to C{f}.

    @return: the result of the L{Deferred} returned by C{f}, or the result
        of C{f} if it returns anything other than a L{Deferred}.

    @raise Exception: If C{f} raises a synchronous exception,
        C{blockingCallFromThread} will raise that exception.  If C{f}
        returns a L{Deferred} which fires with a L{Failure},
        C{blockingCallFromThread} will raise that failure's exception (see
        L{Failure.raiseException}).
    c                 n    t        j                  gi } | j                  j                         y r   )r   maybeDeferredaddBothput)r   ar    kwqueues    r   _callFromThreadz/blockingCallFromThread.<locals>._callFromThread   s-    $$Q11b1uyy!r   )Queuer   get
isinstancer	   FailureraiseException)r   r    r5   r6   r8   r   r7   s    ```  @r   blockingCallFromThreadr>   h   sO    , KKME" ?+YY[F&'//*Mr   )r(   r#   r/   r>   )r   r   r   r
   r    zCallable[_P, _R]r!   z_P.argsr"   z	_P.kwargsr   zdefer.Deferred[_R])__doc__
__future__r   r7   r9   typingr   r   r   r&   r   twisted.internet.interfacesr   twisted.pythonr	   twisted.python.threadpoolr
   r   r   r#   r(   r,   r/   r>   __all__r*   r   r   <module>rF      s    #  $  " ; " 0t_T]' '' ' 	'
 ' 'TS"2 Fr   