B
    .Kc                 @   s  d 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	m
Z
mZmZmZ yddlZdZW n ek
rx   dZY nX ddlmZ ddlmZ eeZejd	krejjZejjZne ZZeoejd
kZG dd dZG dd dZdee  e!e!ee dddZ"dS )zParallel building utilities.    N)sqrt)AnyCallableDictListOptionalSequenceTF)SphinxParallelError)loggingwin32posixc               @   sJ   e Zd ZdZdeddddZdeeee dddd	Z	dd
ddZ
dS )SerialTaskszEHas the same interface as ParallelTasks, but executes tasks directly.   N)nprocreturnc             C   s   d S )N )selfr   r   r   3lib/python3.7/site-packages/sphinx/util/parallel.py__init__#   s    zSerialTasks.__init__)	task_funcargresult_funcr   c             C   s(   |d k	r||}n| }|r$|| d S )Nr   )r   r   r   r   Zresr   r   r   add_task&   s
    
zSerialTasks.add_task)r   c             C   s   d S )Nr   )r   r   r   r   join0   s    zSerialTasks.join)r   )NN)__name__
__module____qualname____doc__intr   r   r   r   r   r   r   r   r   r   r       s
   r   c               @   sx   e Zd ZdZeddddZeeeddddZdeee	e dd	d
dZ
ddddZddddZedddZdS )ParallelTasksz1Executes *nproc* tasks in parallel after forking.N)r   r   c             C   s4   || _ i | _i | _i | _i | _i | _d| _d| _d S )Nr   )r   _result_funcs_args_procs_precvs_precvsWaiting	_pworking_taskid)r   r   r   r   r   r   7   s    zParallelTasks.__init__)pipefuncr   r   c       	   
   C   s   y<t  }|  |d kr$| }n||}W d Q R X d}W nH tk
r } z*d}t|j|d  }|t f}W d d }~X Y nX t 	|j
 |||j
|f d S )NFTr   )r
   ZLogCollectorZcollectBaseException	tracebackformat_exception_only	__class__strip
format_excZconvert_serializablelogssend)	r   r'   r(   r   Z	collectorretZfailederrerrmsgr   r   r   _processH   s    
zParallelTasks._process)r   r   r   r   c       	      C   s~   | j }|  j d7  _ |pdd | j|< || j|< td\}}td}|j| j|||fd}|| j|< || j	|< | 
  d S )Nr   c             S   s   d S )Nr   )r   resultr   r   r   <lambda>]       z(ParallelTasks.add_task.<locals>.<lambda>Ffork)targetargs)r&   r    r!   multiprocessingZPipeZget_contextZProcessr4   r"   r$   	_join_one)	r   r   r   r   tidZprecvZpsendcontextprocr   r   r   r   X   s    



zParallelTasks.add_task)r   c             C   sF   y"x| j r|  std qW W n tk
r@   |    Y nX d S )Ng{Gz?)r%   r<   timeZsleep	Exception	terminate)r   r   r   r   r   f   s    zParallelTasks.joinc             C   sX   xRt | jD ]D}| j|   | j| | j| | j| |  jd8  _qW d S )Nr   )listr#   r"   rB   r    popr%   )r   r=   r   r   r   rB   p   s    zParallelTasks.terminatec       
      C   s   d}x| j  D ]\}}| r| \}}}|r:t| x|D ]}t| q@W | j|| j	|| | j
|   | j | |  jd8  _d}P qW xJ| jr| j| jk r| j \}}	|	| j |< | j
|   |  jd7  _qW |S )NFr   T)r#   itemsZpollZrecvr	   loggerZhandler    rD   r!   r"   r   r%   r$   r   popitemstart)
r   Z
joined_anyr=   r'   excr/   r5   logZnewtidZnewprecvr   r   r   r<   x   s(    

zParallelTasks._join_one)NN)r   r   r   r   r   r   r   r   r4   r   r   r   rB   boolr<   r   r   r   r   r   4   s   
r   
   )	argumentsr   maxbatchr   c                sj   t  }|| |kr,tt|| | dkr8dt|\}}|rR|d7 } fddt|D S )Nr   r   c                s$   g | ]} | |d    qS )r   r   ).0i)rM   	chunksizer   r   
<listcomp>   s    zmake_chunks.<locals>.<listcomp>)lenr   r   divmodrange)rM   r   rN   nargsZnchunksrestr   )rM   rQ   r   make_chunks   s    rX   )rL   )#r   ossysr@   r*   Zmathr   typingr   r   r   r   r   r   r;   ZHAS_MULTIPROCESSINGImportErrorZsphinx.errorsr	   Zsphinx.utilr
   Z	getLoggerr   rF   platformr>   ZForkContextZForkProcessnameZparallel_availabler   r   strr   rX   r   r   r   r   <module>   s,    



]