o
    en                     @  sh  d 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ddlZddl	Z	ddl
Z
ddlmZmZmZ ddlmZ ddlmZmZmZmZ ddlmZ ddlmZmZ dd	lmZ dd
lmZ ddlmZ eee ee f Z eej!ej!f Z!eg df Z"ee!e"e#gdf Z$d"ddZ%dd Z&d#ddZ'd#ddZ(G dd deZ)edd Z*edd Z+ed d! Z,dS )$z<OCRmyPDF's multiprocessing/multithreading abstraction layer.    )annotationsN)ProcessPoolExecutorThreadPoolExecutoras_completed)suppress)CallableIterableTypeUniontqdm)Executorhookimpl)TqdmConsoleInputFileError)remove_all_log_handlersqQueuec                 C  sl   	 z|   }|du rW dS t|j}|| W n ty4   ddl}tdtj	d |j
tj	d Y nw q)a  Listen to the worker processes and forward the messages to logging

    For simplicity this is a thread rather than a process. Only one process
    should actually write to sys.stderr or whatever we're using, so if this is
    made into a process the main application needs to be directed to it.

    See:
    https://docs.python.org/3/howto/logging-cookbook.html#logging-to-a-single-file-from-multiple-processes
    TNr   zLogging problem)file)getlogging	getLoggernamehandle	Exception	tracebackprintsysstderr	print_exc)r   recordloggerr    r#   TD:\Projects\ConvertPro\env\Lib\site-packages\ocrmypdf/builtin_plugins/concurrency.pylog_listener    s   r%   c                  G  s   t d)Nz-A worker process lost access to an input filer   )argsr#   r#   r$   process_sigbus9   s   r'   	user_initUserInitreturnNonec                 C  s|   t  t jt j tt t  t jt W d   n1 sw   Y  t }t	| |
| |tj|  |  dS )z Initialize a process pool workerN)signalSIGINTSIG_IGNr   AttributeErrorSIGBUSr'   r   r   r   setLevel
addHandlerhandlersQueueHandler)r   r(   loglevelrootr#   r#   r$   process_init=   s   

r7   c                 C  sH   ~ ~t t ttjtjh W d    n1 sw   Y  |  d S N)r   r/   r,   Zpthread_sigmaskZ	SIG_BLOCKr0   )r   r(   r5   r#   r#   r$   thread_initT   s   
r9   c                   @  s"   e Zd ZdZdd ZdddZdS )StandardExecutorz+Standard OCRmyPDF concurrent task executor.c                 C  s    t jdd dk ri S tddS )zShim older Pythons that do not have Executor.shutdown(...cancel_futures=).

        Remove this code when support for Python 3.8 is dropped.
        N   )   	   T)cancel_futures)r   version_infodict)selfr#   r#   r$   _cancel_futures_kwargsb   s   
z'StandardExecutor._cancel_futures_kwargsuse_threadsboolmax_workersinttqdm_kwargsr@   worker_initializerr   tasktask_argumentsr   task_finishedc                  sl  |rt d}t}	t}
n	td}t}	t}
tjt	|fd}|
  | jd
i |}|	||
||tdjfda  fdd|D }zHzt|D ]}| }||| qIW n. tyj    jd
ddi|     ty   tjd	ds jd
ddi|    w W |d  n|d  w W d    n1 sw   Y  W d    n1 sw   Y  |  d S )N)targetr&    )rE   initializerZinitargsc                   s   g | ]}  |qS r#   )submit).0r&   executorrI   r#   r$   
<listcomp>   s    z-StandardExecutor._execute.<locals>.<listcomp>waitFZPYTEST_CURRENT_TESTr#   )queuer   r   r9   multiprocessingr   r7   	threadingThreadr%   start
pbar_classr   r   levelr   resultKeyboardInterruptshutdownrB   r   osenvironr   
put_nowaitjoin)rA   rC   rE   rG   rH   rI   rJ   rK   Z	log_queueZexecutor_classrO   listenerZpbarfuturesfuturer]   r#   rR   r$   _executek   sF   

 zStandardExecutor._executeN)rC   rD   rE   rF   rG   r@   rH   r   rI   r   rJ   r   rK   r   )__name__
__module____qualname____doc__rB   rg   r#   r#   r#   r$   r:   _   s    	r:   c                 C  s
   t | dS )N)r[   )r:   )Zprogressbar_classr#   r#   r$   get_executor   s   
rl   c                   C  s   t S r8   r   r#   r#   r#   r$   get_progressbar_class   s   rm   c                   C  s   t jttjdS )N)stream)r   StreamHandlerr   r   r   r#   r#   r#   r$   get_logging_console   s   rp   )r   r   )r   r   r(   r)   r*   r+   )-rk   
__future__r   r   logging.handlersrW   r`   rV   r,   r   rX   concurrent.futuresr   r   r   
contextlibr   typingr   r   r	   r
   r   Zocrmypdfr   r   Zocrmypdf._loggingr   Zocrmypdf.exceptionsr   Zocrmypdf.helpersr   ZFuturesExecutorClassr   r)   rF   Z
WorkerInitr%   r'   r7   r9   r:   rl   rm   rp   r#   r#   r#   r$   <module>   sB   


F

