Ë
    òT•jq  ã                   óè   — 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y)é    N)Úsupportc                  ó\   — t        j                  «       t        t        j                  «      fS ©N)Ú_threadÚ_countÚlenÚ	threadingÚ	_dangling© ó    ú4/usr/lib/python3.12/test/support/threading_helper.pyÚthreading_setupr      s   € Ü�>‰>ÓœS¤×!4Ñ!4Ó5Ð5Ð5r   c                  ób  — | \  }}d}t        j                  |d¬«      D ]6  }t        t        j                  «      }t        j                  «       }||k  sŒ6 y  dt         _        t        j                  d|d›d|› d|› d	› dt        «      › �
«       |D ]  }t        j                  d
|›�«       Œ y )Ng      ð?F©ÚerrorTz2threading_cleanup() failed to clean up threads in ú.1fz  seconds
  before: thread count=z, dangling=z
  after: thread count=zDangling thread: )
r   Úsleeping_retryÚlistr	   r
   r   r   Úenvironment_alteredÚprint_warningr   )Úoriginal_valuesÚ
orig_countÚorig_ndanglingÚtimeoutÚ_Údangling_threadsÚcountÚthreads           r   Úthreading_cleanupr      sÒ   € Ø!0Ñ€J�à€GÜ×#Ñ# G°5Ô9ò ˆô  ¤	× 3Ñ 3Ó4ÐÜ—‘Ó ˆà�JÓÙðð #'„GÔÜ×ÑðØ�cˆ]ð "Ø", ¨[¸Ð8Hð I!Ø!&  {´3Ð7GÓ3HÐ2Ið	KôLð
 #ò >ˆÜ×ÑÐ 1°&°Ð<Õ=ñ>r   c                 óB   ‡ — t        j                  ‰ «      ˆ fd„«       }|S )zƒUse this function when threads are being used.  This will
    ensure that the threads are cleaned up even when the test fails.
    c                  óN   •— t        «       }	  ‰| Ž t        |Ž  S # t        |Ž  w xY wr   )r   r   )ÚargsÚkeyÚfuncs     €r   Ú	decoratorzreap_threads.<locals>.decorator>   s)   ø€ äÓˆð	$Ù˜�;ä˜sÒ#øÔ˜sÒ#ús   � š
$)Ú	functoolsÚwraps)r$   r%   s   ` r   Úreap_threadsr(   :   s(   ø€ ô ‡_�_�TÓó$ó ð$ð Ðr   c              #   ó¸  K  — | €t         j                  } t        j                  «       }	 d–— t	        j
                  «       }t        j                  | d¬«      D ]1  }t        j                  «        t        j                  «       }||k  sŒ1 y t	        j
                  «       |z
  }d|z
  › d|d›d|› d|› d	�	}t        |«      ‚# t	        j
                  «       }t        j                  | d¬«      D ]1  }t        j                  «        t        j                  «       }||k  sŒ1 w  t	        j
                  «       |z
  }d|z
  › d|d›d|› d|› d	�	}t        |«      ‚xY w­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.
    NFr   z!wait_threads() failed to cleanup z threads after r   z seconds (count: z, old count: ú))	r   ÚSHORT_TIMEOUTr   r   ÚtimeÚ	monotonicr   Ú
gc_collectÚAssertionError)r   Ú	old_countÚ
start_timer   r   ÚdtÚmsgs          r   Úwait_threads_exitr4   H   sk  è ø€ ð €Ü×'Ñ'ˆÜ—‘Ó €Ið&Ûä—^‘^Ó%ˆ
Ü×'Ñ'¨°uÔ=ò 
	&ˆAÜ×ÑÔ Ü—N‘NÓ$ˆEØ˜	Ó!Ùð	
	&ô —‘Ó! JÑ.ˆBØ6°u¸yÑ7HÐ6Ið J$Ø$& s 8ð ,Ø#˜W M°)°¸Að?ˆCô ! Ó%Ð%øô —^‘^Ó%ˆ
Ü×'Ñ'¨°uÔ=ò 
	&ˆAÜ×ÑÔ Ü—N‘NÓ$ˆEØ˜	Ó!Ùð	
	&ô —‘Ó! JÑ.ˆBØ6°u¸yÑ7HÐ6Ið J$Ø$& s 8ð ,Ø#˜W M°)°¸Að?ˆCô ! Ó%Ð%üs)   ‚'EªC ®AEÂ
8EÃAEÄ8EÅEc                 óŽ   — |€t         j                  }| j                  |«       | j                  «       rd|d›d�}t	        |«      ‚y)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   r   r3   s      r   Újoin_threadr8   k   sJ   € ð €Ü×'Ñ'ˆØ
‡K�K�ÔØ‡�ÔØ-¨g°c¨]¸(ÐCˆÜ˜SÓ!Ð!ð r   c              #   ó8  K  — 	 dd l }t        | «      } g }	 	 | D ]#  }|j                  «        |j	                  |«       Œ% 	 d –— 	 |r |«        t        j                  «       }t        dd«      D ]Œ  }|dz  }|D ]2  }|j                  t        |t        j                  «       z
  d«      «       Œ4 |D �cg c]  }|j                  «       sŒ|‘Œ }}|s n,t
        j                  sŒtt        dt        |«      |fz  «       ŒŽ |D �cg c]  }|j                  «       sŒ|‘Œ }}|r8|�|j                  t         j"                  «       t%        dt        |«      z  «      ‚y # t        $ r d }Y �Œ^w xY w#  t
        j                  r"t        dt        | «      t        |«      fz  «       ‚ xY wc c}w c c}w # |D �cg c]  }|j                  «       sŒ|‘Œ nc c}w }}|r8|�|j                  t         j"                  «       t%        dt        |«      z  «      ‚w xY w# 	 |r |«        t        j                  «       }t        dd«      D ]’  }|dz  }|D ]2  }|j                  t        |t        j                  «       z
  d«      «       Œ4 |D �cg c]  }|j                  «       sŒ|‘Œ nc c}w }}|s n,t
        j                  sŒzt        dt        |«      |fz  «       Œ” |D �cg c]  }|j                  «       sŒ|‘Œ nc c}w }}|r8|�|j                  t         j"                  «       t%        dt        |«      z  «      ‚w # |D �cg c]  }|j                  «       sŒ|‘Œ nc c}w }}|r8|�|j                  t         j"                  «       t%        dt        |«      z  «      ‚w xY wxY w­w)	Nr   z/Can't start %d threads, only %d threads startedé   é   é<   g{®Gáz„?z7Unable to join %d threads during a period of %d minuteszUnable to join %d threads)ÚfaulthandlerÚImportErrorr   ÚstartÚappendr   ÚverboseÚprintr   r,   r-   Úranger6   Úmaxr7   Údump_tracebackÚsysÚstdoutr/   )ÚthreadsÚunlockr=   ÚstartedÚtÚendtimer   s          r   Ústart_threadsrM   w   sZ  è ø€ ðÛô �7‹m€GØ€GðQð	Øò "�Ø—‘”	Ø—‘˜qÕ!ñ"ó 	ð	QÙÙ”Ü—n‘nÓ&ˆGÜ   B›<ò 	B�Ø˜2‘�Ø ò B�AØ—F‘Fœ3˜w¬¯©Ó)9Ñ9¸4Ó@ÕAðBà&-Ö> °·±µš1Ð>�Ð>ÙÙÜ—?“?Üð 'Ü*-¨g«,¸Ð)@ñAõ Bð	Bð #*Ö:˜Q¨Q¯Z©Z­\’qÐ:ˆGÐ:ÙØÐ+Ø ×/Ñ/´·
±
Ô;Ü$Ð%@Ä3ÀwÃ<Ñ%OÓPÐPð øôC ò à‹ðûð	Ü�ŠÜÐGÜ˜7“|¤S¨£\Ð2ñ3ô 4àüò ?ùò ;ø 'Ö:˜Q¨Q¯Z©Z­\’qÑ:ùÒ:ˆGÐ:ÙØÐ+Ø ×/Ñ/´·
±
Ô;Ü$Ð%@Ä3ÀwÃ<Ñ%OÓPÐPð ûð!	QÙÙ”Ü—n‘nÓ&ˆGÜ   B›<ò 	B�Ø˜2‘�Ø ò B�AØ—F‘Fœ3˜w¬¯©Ó)9Ñ9¸4Ó@ÕAðBà&-Ö> °·±µš1Ñ>ùÒ>�Ð>ÙÙÜ—?“?Üð 'Ü*-¨g«,¸Ð)@ñAõ Bð	Bð #*Ö:˜Q¨Q¯Z©Z­\’qÑ:ùÒ:ˆGÐ:ÙØÐ+Ø ×/Ñ/´·
±
Ô;Ü$Ð%@Ä3ÀwÃ<Ñ%OÓPÐPð øð #*Ö:˜Q¨Q¯Z©Z­\’qÑ:ùÒ:ˆGÐ:ÙØÐ+Ø ×/Ñ/´·
±
Ô;Ü$Ð%@Ä3ÀwÃ<Ñ%OÓPÐPð ÿs  ‚N„E ˆN—(E* ¿H ÁA,F, Â1F"ÃF"ÃF, Ã"F, Ã=NÄF'ÄF'Ä=NÅE'Å#NÅ&E'Å'NÅ*5FÆH Æ"F, Æ'NÆ,HÆ1GÇGÇAHÈNÈNÈA,L2É?J
ÊJ
ÊL2Ê6L2ËNËK0Ë+K0Ë/ANÌ2NÌ7MÍMÍANÎNÎNc                   ó(   — e Zd ZdZd„ Zd„ Zd„ Zd„ Zy)Ú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                 óJ   — d | _         d | _        d | _        d | _        d | _        y r   )Úexc_typeÚ	exc_valueÚexc_tracebackr   Ú	_old_hook©Úselfs    r   Ú__init__z"catch_threading_exception.__init__Á   s&   € ØˆŒØˆŒØ!ˆÔØˆŒØˆ�r   c                 óŒ   — |j                   | _         |j                  | _        |j                  | _        |j                  | _        y r   )rQ   rR   rS   r   )rV   r"   s     r   Ú_hookzcatch_threading_exception._hookÈ   s1   € ØŸ™ˆŒØŸ™ˆŒØ!×/Ñ/ˆÔØ—k‘kˆ�r   c                 óZ   — t         j                  | _        | j                  t         _        | S r   )r	   Ú
excepthookrT   rY   rU   s    r   Ú	__enter__z#catch_threading_exception.__enter__Î   s    € Ü"×-Ñ-ˆŒØ#Ÿz™zŒ	ÔØˆr   c                 ó>   — | j                   t        _        | `| `| `| `y r   )rT   r	   r[   rQ   rR   rS   r   )rV   Úexc_infos     r   Ú__exit__z"catch_threading_exception.__exit__Ó   s#   € Ø#Ÿ~™~Œ	ÔØˆMØˆNØÐØ‰Kr   N)Ú__name__Ú
__module__Ú__qualname__Ú__doc__rW   rY   r\   r_   r   r   r   rO   rO   ¢   s   „ ñò<ò"òó
r   rO   Úreturnc                  ó†   — t         j                  dk(  rt         j                  j                  S t         j                  dk(  ryy)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)rF   ÚplatformÚ_emscripten_infoÚpthreadsr   r   r   Ú_can_start_threadrk   Û   s6   € ô ‡|�|�|Ò#Ü×#Ñ#×,Ñ,Ð,Ü	�‰˜Ò	Øð r   F)Úmodulec                 óv   — d}| rt         st        j                  |«      ‚yt        j                  t         |«      S )z†Skip 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)rl   r3   s     r   Úrequires_working_threadingrr   ð   s;   € ð
 '€CÙÝÜ×#Ñ# CÓ(Ð(ð  ô ×"Ñ"Ô#3°SÓ9Ð9r   r   )r   Ú
contextlibr&   rF   r	   r,   ro   Útestr   r   r   r(   Úcontextmanagerr4   r8   rM   rO   Úboolrk   rn   rr   r   r   r   ú<module>rw      s“   ðÛ Û Û Û 
Û Û Û å ò6ò>ò<ð ×Ñò&ó ð&óD	"ð ×Ñò'Qó ð'Q÷T6ñ 6ðr˜4ó ñ& %Ó&Ð à).õ 
:r   