o
    b                     @   sX   d Z ddlZddlmZ ddlmZ dd Zdd Zd	d
 Z	dd Z
dd Zg dZdS )zY
Extended thread dispatching support.

For basic support see reactor threading API docs.
    N)defer)failurec                    s4   t    fdd}|j||g|R 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                    s(   | r  j| d S   j| d S N)callFromThreadcallbackerrback)successresultdreactor :/usr/lib/python3/dist-packages/twisted/internet/threads.pyonResult*   s   z#deferToThreadPool.<locals>.onResult)r   DeferredcallInThreadWithCallback)r   
threadpoolfargskwargsr   r   r
   r   deferToThreadPool   s   r   c                 O   s*   ddl m} t|| | g|R 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   r   r   r   deferToThread5   s   r   c                 C   s"   | D ]\}}}||i | qdS )z"
    Run a list of functions.
    Nr   )	tupleListr   r   r   r   r   r   _runMultipleF   s   r   c                 C   s   ddl m} |t|  dS )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   r   r   r   callMultipleInThreadN   s   r   c                    sD   t    fdd}| |  }t|tjr |  |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                     s(   t jg R i } | j d S r   )r   maybeDeferredaddBothput)r	   ar   kwqueuer   r   _callFromThreadq   s   z/blockingCallFromThread.<locals>._callFromThread)Queuer   get
isinstancer   FailureraiseException)r   r   r#   r$   r&   r	   r   r"   r   blockingCallFromThreadY   s   
r,   )r   r   r   r,   )__doc__r%   r'   r   r   twisted.pythonr   r   r   r   r   r,   __all__r   r   r   r   <module>   s   $#