B
    \l                 @   s   d Z ddlmZ ddlZddlZddlZddlmZ ddlm	Z	 yddl
Z
W n ek
rd   dZ
Y nX ddlmZ ddlmZ eeZe
oejdkZG d	d
 d
eZG dd deZdddZdS )z
    sphinx.util.parallel
    ~~~~~~~~~~~~~~~~~~~~

    Parallel building utilities.

    :copyright: Copyright 2007-2019 by the Sphinx team, see AUTHORS.
    :license: BSD, see LICENSE for details.
    )absolute_importN)sqrt)	iteritems)SphinxParallelError)loggingposixc               @   s,   e Zd ZdZd
ddZdddZdd	 ZdS )SerialTaskszEHas the same interface as ParallelTasks, but executes tasks directly.   c             C   s   d S )N )selfnprocr
   r
   3lib/python3.7/site-packages/sphinx/util/parallel.py__init__*   s    zSerialTasks.__init__Nc             C   s(   |d k	r||}n| }|r$|| d S )Nr
   )r   	task_funcargresult_funcZresr
   r
   r   add_task.   s
    
zSerialTasks.add_taskc             C   s   d S )Nr
   )r   r
   r
   r   join7   s    zSerialTasks.join)r	   )NN)__name__
__module____qualname____doc__r   r   r   r
   r
   r
   r   r   '   s   

	r   c               @   s:   e Zd ZdZdd Zdd ZdddZd	d
 Zdd ZdS )ParallelTasksz1Executes *nproc* tasks in parallel after forking.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   ?   s    zParallelTasks.__init__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   pipefuncr   Z	collectorZretZfailederrerrmsgr
   r
   r   _processQ   s    
zParallelTasks._processNc             C   st   | j }|  j d7  _ |pdd | j|< || j|< td\}}tj| j|||fd}|| j|< || j|< | 	  d S )Nr	   c             S   s   d S )Nr
   )r   resultr
   r
   r   <lambda>f   s    z(ParallelTasks.add_task.<locals>.<lambda>F)targetargs)
r   r   r   multiprocessingZPipeZProcessr,   r   r   	_join_one)r   r   r   r   tidZprecvZpsendprocr
   r
   r   r   b   s    


zParallelTasks.add_taskc             C   s   x| j r|   qW d S )N)r   r2   )r   r
   r
   r   r   o   s    zParallelTasks.joinc       	      C   s   xt | jD ]\}}| r| \}}}|r6t| x|D ]}t| q<W | j|| j	|| | j
|   | j| |  jd8  _P qW td xJ| jr| j| jk r| j \}}|| j|< | j
|   |  jd7  _qW d S )Nr	   g{Gz?)r   r   ZpollZrecvr   loggerZhandler   popr   r   r   r   timeZsleepr   r   popitemstart)	r   r3   r(   excr&   r-   logZnewtidZnewprecvr
   r
   r   r2   t   s$    


zParallelTasks._join_one)NN)	r   r   r   r   r   r,   r   r   r2   r
   r
   r
   r   r   <   s   
r   
   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)	arguments	chunksizer
   r   
<listcomp>   s    zmake_chunks.<locals>.<listcomp>)lenintr   divmodrange)r?   r   ZmaxbatchnargsZnchunksrestr
   )r?   r@   r   make_chunks   s    rH   )r<   )r   Z
__future__r   osr7   r!   Zmathr   Zsixr   r1   ImportErrorZsphinx.errorsr   Zsphinx.utilr   Z	getLoggerr   r5   nameZparallel_availableobjectr   r   rH   r
   r
   r
   r   <module>
   s"   

O