
    hH                         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 d Z	d Z
d Zej        dd            ZddZej        dd            Z G d	 d
          ZdefdZ e            ZdddZdS )    N)supportc                  d    t          j                    t          j                                        fS N)_thread_count	threading	_danglingcopy     4/usr/lib/python3.11/test/support/threading_helper.pythreading_setupr      s$    >Y0557777r   c                     d}t          |          D ]}t          j                    t          j        f}|| k    r d S |srdt
          _        |d         }t          j        d|d         | d         z
   d|d          dt          |           d           |D ]}t          j        d	|           d }d }t          j
        d
           t          j                     d S )Nd   T   z&threading_cleanup() failed to cleanup r   z threads (count: z, dangling: )zDangling thread: {Gz?)ranger   r   r   r	   r   environment_alteredprint_warninglentimesleep
gc_collect)original_values
_MAX_COUNTcountvaluesdangling_threadsthreads         r   threading_cleanupr!      s6   Jz""  !!9#66_$$EE 	$*.G'%ay! #H%+AY1C%C#H #H-3AY#H #H 033C/D/D#H #H #H I I I + F F%&D&&D&DEEEE  $
4+ r   c                 F     t          j                    fd            }|S )zUse this function when threads are being used.  This will
    ensure that the threads are cleaned up even when the test fails.
    c                  Z    t                      }	  |  t          |  S # t          |  w xY wr   )r   r!   )argskeyfuncs     r   	decoratorzreap_threads.<locals>.decorator;   s<    	$4;s###s###s    *)	functoolswraps)r&   r'   s   ` r   reap_threadsr*   7   s;     _T$ $ $ $ $ r   c              #     K   | t           j        } t          j                    }	 dV  t	          j                    }|| z   }	 t          j                    }||k    rdS t	          j                    |k    r8t	          j                    |z
  }d||z
   d|dd| d| d	}t          |          t	          j        d	           t          j                     # t	          j                    }|| z   }	 t          j                    }||k    rnwt	          j                    |k    r8t	          j                    |z
  }d||z
   d|dd| d| d	}t          |          t	          j        d	           t          j                     w xY w)
aH  
    bpo-31234: Context manager to wait until all threads created in the with
    statement exit.

    Use _thread.count() to check if threads exited. Indirectly, wait until
    threads exit the internal t_bootstrap() C function of the _thread module.

    threading_setup() and threading_cleanup() are designed to emit a warning
    if a test leaves running threads in the background. This context manager
    is designed to cleanup threads started by the _thread.start_new_thread()
    which doesn't allow to wait for thread exit, whereas thread.Thread has a
    join() method.
    NTz!wait_threads() failed to cleanup z threads after .1fz seconds (count: z, old count: r   r   )	r   SHORT_TIMEOUTr   r   r   	monotonicAssertionErrorr   r   )timeout	old_count
start_timedeadliner   dtmsgs          r   wait_threads_exitr6   E   s      '  I!^%%
'	!N$$E	!!~(**^%%
2C59;L C C(*9C C"'C C6?C C C %S)))Ju   	! ^%%
'	!N$$E	!!~(**^%%
2C59;L C C(*9C C"'C C6?C C C %S)))Ju   	! 	! 	! 	! 	!s   C B,F c                     |t           j        }|                     |           |                                 rd|dd}t	          |          dS )zcJoin a thread. Raise an AssertionError if the thread is still alive
    after timeout seconds.
    Nzfailed to join the thread in r,   z seconds)r   r-   joinis_aliver/   )r    r0   r5   s      r   join_threadr:   j   s`     '
KK "CgCCCCS!!!" "r   c              #   b  K   dd l }t          |           } g }	 	 | D ]+}|                                 |                    |           ,n@#  t          j        r.t          dt          |           t          |          fz              xY wd V  	 |r
 |             t          j	                    }t          dd          D ]}|dz  }|D ]9}|                    t          |t          j	                    z
  d                     :d |D             }|s n.t          j        r!t          dt          |          |fz             d	 |D             }|r>|                    t          j                   t!          d
t          |          z            d S # d	 |D             }|r>|                    t          j                   t!          d
t          |          z            w xY w# 	 |r
 |             t          j	                    }t          dd          D ]}|dz  }|D ]9}|                    t          |t          j	                    z
  d                     :d |D             }|s n.t          j        r!t          dt          |          |fz             d	 |D             }|r>|                    t          j                   t!          d
t          |          z            nQ# d	 |D             }|r>|                    t          j                   t!          d
t          |          z            w xY ww xY w)Nr   z/Can't start %d threads, only %d threads startedr      <   r   c                 :    g | ]}|                                 |S r   r9   .0ts     r   
<listcomp>z!start_threads.<locals>.<listcomp>   s%    >>>>1>>>r   z7Unable to join %d threads during a period of %d minutesc                 :    g | ]}|                                 |S r   r?   r@   s     r   rC   z!start_threads.<locals>.<listcomp>   s%    :::QQZZ\\:q:::r   zUnable to join %d threads)faulthandlerliststartappendr   verboseprintr   r   r.   r   r8   maxdump_tracebacksysstdoutr/   )threadsunlockrE   startedrB   endtimer0   s          r   start_threadsrS   v   s     7mmGGQ	 " "			q!!!!"	 4G7||S\\23 4 4 4	Q n&&G B<< 	B 	B2  B BAFF3w)9)994@@AAAA>>g>>> E? B '*-g,,)@A B B B ;:':::G Q++CJ777$%@3w<<%OPPPQ Q ;:':::G Q++CJ777$%@3w<<%OPPPPPPP%	Q n&&G B<< 	B 	B2  B BAFF3w)9)994@@AAAA>>g>>> E? B '*-g,,)@A B B B ;:':::G Q++CJ777$%@3w<<%OPPPQ ;:':::G Q++CJ777$%@3w<<%OPPPPPPPPPPPsF   .A	 G 	=BG B0F AGL.B0KAL.AL**L.c                   *    e Zd ZdZd Zd Zd Zd ZdS )catch_threading_exceptiona  
    Context manager catching threading.Thread exception using
    threading.excepthook.

    Attributes set when an exception is caught:

    * exc_type
    * exc_value
    * exc_traceback
    * thread

    See threading.excepthook() documentation for these attributes.

    These attributes are deleted at the context manager exit.

    Usage:

        with threading_helper.catch_threading_exception() as cm:
            # code spawning a thread which raises an exception
            ...

            # check the thread exception, use cm attributes:
            # exc_type, exc_value, exc_traceback, thread
            ...

        # exc_type, exc_value, exc_traceback, thread attributes of cm no longer
        # exists at this point
        # (to avoid reference cycles)
    c                 L    d | _         d | _        d | _        d | _        d | _        d S r   )exc_type	exc_valueexc_tracebackr    	_old_hookselfs    r   __init__z"catch_threading_exception.__init__   s*    !r   c                 f    |j         | _         |j        | _        |j        | _        |j        | _        d S r   )rW   rX   rY   r    )r\   r$   s     r   _hookzcatch_threading_exception._hook   s,    !/kr   c                 J    t           j        | _        | j        t           _        | S r   )r   
excepthookrZ   r_   r[   s    r   	__enter__z#catch_threading_exception.__enter__   s    "-#z	r   c                 8    | j         t          _        | `| `| `| `d S r   )rZ   r   ra   rW   rX   rY   r    )r\   exc_infos     r   __exit__z"catch_threading_exception.__exit__   s%    #~	MNKKKr   N)__name__
__module____qualname____doc__r]   r_   rb   re   r   r   r   rU   rU      sZ         <  " " "  
    r   rU   returnc                  l    t           j        dk    rt           j        j        S t           j        dk    rdS dS )ay  Detect whether Python can start new threads.

    Some WebAssembly platforms do not provide a working pthread
    implementation. Thread support is stubbed and any attempt
    to create a new thread fails.

    - wasm32-wasi does not have threading.
    - wasm32-emscripten can be compiled with or without pthread
      support (-s USE_PTHREADS / __EMSCRIPTEN_PTHREADS__).
    
emscriptenwasiFT)rM   platform_emscripten_infopthreadsr   r   r   _can_start_threadrq      s6     ||###,,			u tr   F)modulec                 x    d}| rt           st          j        |          dS t          j        t           |          S )zSkip tests or modules that require working threading.

    Can be used as a function/class decorator or to skip an entire module.
    zrequires threading supportN)can_start_threadunittestSkipTest
skipUnless)rr   r5   s     r   requires_working_threadingrx      sJ    
 'C : 	)#C(((	) 	) "#3S999r   r   )r   
contextlibr(   rM   r   r   ru   testr   r   r!   r*   contextmanagerr6   r:   rS   rU   boolrq   rt   rx   r   r   r   <module>r}      si            



            8 8 8  6   !! !! !! !!H	" 	" 	" 	" "Q "Q "Q "QJ6 6 6 6 6 6 6 6r4    & %$&& ). 
: 
: 
: 
: 
: 
: 
:r   