B
    Å S]A  ã               @   s¢   d Z dZddlZddlmZ ddlZddlZddlZddlZddl	Z	e 
¡ Zdadd„ Ze e¡ G dd	„ d	eƒZd
d„ ZG dd„ dejƒZG dd„ dejƒZdS )zImplements ThreadPoolExecutor.z"Brian Quinlan (brian@sweetapp.com)é    N)Ú_baseFc              C   sJ   da tt ¡ ƒ} x| D ]\}}| d ¡ qW x| D ]\}}| ¡  q2W d S )NT)Ú	_shutdownÚlistÚ_threads_queuesÚitemsÚputÚjoin)r   ÚtÚq© r   ú*lib/python3.7/concurrent/futures/thread.pyÚ_python_exit!   s    r   c               @   s   e Zd Zdd„ Zdd„ ZdS )Ú	_WorkItemc             C   s   || _ || _|| _|| _d S )N)ÚfutureÚfnÚargsÚkwargs)Úselfr   r   r   r   r   r   r   Ú__init__.   s    z_WorkItem.__init__c          
   C   sf   | j  ¡ sd S y| j| j| jŽ}W n2 tk
rT } z| j  |¡ d } W d d }~X Y nX | j  |¡ d S )N)r   Zset_running_or_notify_cancelr   r   r   ÚBaseExceptionÚset_exceptionZ
set_result)r   ÚresultÚexcr   r   r   Úrun4   s    
z_WorkItem.runN)Ú__name__Ú
__module__Ú__qualname__r   r   r   r   r   r   r   -   s   r   c             C   sÚ   |d k	rPy||Ž  W n: t k
rN   tjjddd | ƒ }|d k	rJ| ¡  d S X y`xZ|jdd}|d k	rt| ¡  ~qT| ƒ }tsŒ|d ksŒ|jr¨|d k	ršd|_| d ¡ d S ~qTW W n$ t k
rÔ   tjjddd Y nX d S )NzException in initializer:T)Úexc_info)ÚblockzException in worker)	r   r   ZLOGGERZcriticalÚ_initializer_failedÚgetr   r   r   )Zexecutor_referenceZ
work_queueÚinitializerÚinitargsZexecutorÚ	work_itemr   r   r   Ú_workerB   s2    

r$   c               @   s   e Zd ZdZdS )ÚBrokenThreadPoolzR
    Raised when a worker thread in a ThreadPoolExecutor failed initializing.
    N)r   r   r   Ú__doc__r   r   r   r   r%   f   s   r%   c               @   sZ   e Zd Ze ¡ jZddd„Zdd„ Ze	j
jje_dd	„ Zd
d„ Zddd„Ze	j
jje_dS )ÚThreadPoolExecutorNÚ r   c             C   s   |dkrt  ¡ pdd }|dkr(tdƒ‚|dk	r@t|ƒs@tdƒ‚|| _t ¡ | _t	ƒ | _
d| _d| _t ¡ | _|p|d|  ¡  | _|| _|| _dS )	a•  Initializes a new ThreadPoolExecutor instance.

        Args:
            max_workers: The maximum number of threads that can be used to
                execute the given calls.
            thread_name_prefix: An optional name prefix to give our threads.
            initializer: A callable used to initialize worker threads.
            initargs: A tuple of arguments to pass to the initializer.
        Né   é   r   z"max_workers must be greater than 0zinitializer must be a callableFzThreadPoolExecutor-%d)ÚosÚ	cpu_countÚ
ValueErrorÚcallableÚ	TypeErrorÚ_max_workersÚqueueZSimpleQueueÚ_work_queueÚsetÚ_threadsÚ_brokenr   Ú	threadingZLockÚ_shutdown_lockÚ_counterÚ_thread_name_prefixÚ_initializerÚ	_initargs)r   Zmax_workersZthread_name_prefixr!   r"   r   r   r   r   q   s     

zThreadPoolExecutor.__init__c           	   O   sÀ   t | ƒdkr| ^}}} n>| s&tdƒ‚n0d|krB| d¡}| ^}} ntdt | ƒd  ƒ‚|jZ |jrnt|jƒ‚|jr|tdƒ‚trˆtdƒ‚t 	¡ }t
||| |ƒ}|j |¡ | ¡  |S Q R X d S )Né   zDdescriptor 'submit' of 'ThreadPoolExecutor' object needs an argumentr   z6submit expected at least 1 positional argument, got %dr)   z*cannot schedule new futures after shutdownz6cannot schedule new futures after interpreter shutdown)Úlenr/   Úpopr7   r5   r%   r   ÚRuntimeErrorr   ZFuturer   r2   r   Ú_adjust_thread_count)r   r   r   r   ÚfÚwr   r   r   Úsubmit‘   s*    



zThreadPoolExecutor.submitc             C   s‚   | j fdd„}t| jƒ}|| jk r~d| jp,| |f }tj|tt 	| |¡| j | j
| jfd}d|_| ¡  | j |¡ | j t|< d S )Nc             S   s   |  d ¡ d S )N)r   )Ú_r
   r   r   r   Ú
weakref_cb³   s    z;ThreadPoolExecutor._adjust_thread_count.<locals>.weakref_cbz%s_%d)ÚnameÚtargetr   T)r2   r=   r4   r0   r9   r6   ZThreadr$   ÚweakrefÚrefr:   r;   ZdaemonÚstartÚaddr   )r   rE   Znum_threadsZthread_namer	   r   r   r   r@   °   s    



z'ThreadPoolExecutor._adjust_thread_countc          	   C   sd   | j T d| _xFy| j ¡ }W n tjk
r6   P Y nX |d k	r|j t| jƒ¡ qW W d Q R X d S )NzBA thread initializer failed, the thread pool is not usable anymore)	r7   r5   r2   Z
get_nowaitr1   ZEmptyr   r   r%   )r   r#   r   r   r   r   Å   s    z&ThreadPoolExecutor._initializer_failedTc          	   C   sD   | j  d| _| j d ¡ W d Q R X |r@x| jD ]}| ¡  q0W d S )NT)r7   r   r2   r   r4   r   )r   Úwaitr	   r   r   r   ÚshutdownÒ   s    zThreadPoolExecutor.shutdown)Nr(   Nr   )T)r   r   r   Ú	itertoolsÚcountÚ__next__r8   r   rC   r   ÚExecutorr&   r@   r   rM   r   r   r   r   r'   l   s   
 

r'   )r&   Ú
__author__ÚatexitZconcurrent.futuresr   rN   r1   r6   rH   r+   ÚWeakKeyDictionaryr   r   r   ÚregisterÚobjectr   r$   ZBrokenExecutorr%   rQ   r'   r   r   r   r   Ú<module>   s    	
$