a
    'fZ                     @   s  d dl mZ d dlmZ d dlmZ dZee d	dd e
dD Zd	dd e
dD Zd d	lmZ ejZd dlZd dlZd dlZd dlZzd dlZW n ey   d dlZY n0 d dlZd dlZd dlZd d
lmZ dZdd ZG dd deZG dd dejZeG dd dej Z!eG dd dej Z"eG dd dej Z#eG dd dej$Z$eG dd dej%Z%eG dd dej%Z&eG dd dej'Z'eG d d! d!ej%Z(eG d"d# d#ej)Z)eG d$d% d%ej*Z*eG d&d' d'ej+Z+e,d(kre-  dS ))    )print_function)xrangeNa  from gevent import monkey; monkey.patch_all()
from gevent.event import Event
from gevent.lock import RLock, Semaphore, BoundedSemaphore
from gevent.thread import allocate_lock as Lock
import threading
threading.Event = Event
threading.Lock = Lock
# NOTE: We're completely patching around the allocate_lock
# patch we try to do with RLock; our monkey patch doesn't
# behave this way, but we do it in tests to make sure that
# our RLock implementation behaves correctly by itself.
# However, we must test the patched version too, so make it
# available.
threading.NativeRLock = threading.RLock
threading.RLock = RLock
threading.Semaphore = Semaphore
threading.BoundedSemaphore = BoundedSemaphore

c                 c   s   | ]}d | V  qdS )z            %sN .0liner   r   l/var/www/staging/api/virtual_environments/venv/lib/python3.9/site-packages/gevent/tests/test__threading_2.py	<genexpr>       r
   c                 c   s   | ]}d | V  qdS )z                %sNr   r   r   r   r	   r
      r   )support)
lock_testsFc                 C   s   t tjotjd| S )Nz#SKIPPED: Timeout on PyPy3 on Travis)unittestskipIf	greentestZPYPY3ZRUNNING_ON_CI)clsr   r   r	   skipDueToHang4   s    
r   c                   @   s,   e Zd Zdd Zdd Zdd Zdd Zd	S )
Counterc                 C   s
   d| _ d S )Nr   valueselfr   r   r	   __init__;   s    zCounter.__init__c                 C   s   |  j d7  _ d S N   r   r   r   r   r	   inc>   s    zCounter.incc                 C   s   |  j d8  _ d S r   r   r   r   r   r	   decA   s    zCounter.decc                 C   s   | j S Nr   r   r   r   r	   getD   s    zCounter.getN)__name__
__module____qualname__r   r   r   r   r   r   r   r	   r   :   s   r   c                   @   s   e Zd Zdd Zdd ZdS )
TestThreadc                 C   s,   t jj| |d || _|| _|| _|| _d S )N)name)	threadingThreadr   testcasesemamutexnrunning)r   r#   r&   r'   r(   r)   r   r   r	   r   I   s
    zTestThread.__init__c              	   C   s&  t   d }tr&td| j|d f  | j | jB | j  trTt| j d | j	
| j d W d    n1 s|0    Y  t| trtd| jd | jJ | j  | j	| j d trtd	| j| j f  W d    n1 s0    Y  W d    n1 s0    Y  d S )
Ng     @ztask %s will run for %.1f usecg    .Aztasks are running   taskdoner   z$%s is finished. %d tasks are running)randomverboseprintr#   r'   r(   r)   r   r   r&   ZassertLessEqualtimesleepr   ZassertGreaterEqual)r   delayr   r   r	   runP   s*    

2

zTestThread.runN)r   r    r!   r   r3   r   r   r   r	   r"   H   s   r"   c                   @   s   e Zd Zdd Zdd Zdd Zdd Zd	d
 Zdd Zdd Z	dd Z
eddd Zeeed ddd Zeedsdd ZdS )ThreadTestsc                 C   s&  d}t jdd}t  }t }g }t|D ]h}td| | |||}|| d|_t|dr| 	|j
 | |j | tdt| |  q*trtd |D ]^}|| | | |j t|dr| |j
d	 | |j
d u  | td
t| qtrtd | | d	 d S )N
   r*   r   z<thread %d>Fidentz<TestThread\(.*, initial\)>z!waiting for all tasks to completer   z<TestThread\(.*, \w+ -?\d+\)>zall tasks done)r$   BoundedSemaphoreRLockr   ranger"   appenddaemonhasattrassertIsNoner6   assertFalse
assertTruerematchreprstartr.   r/   joinis_alive__dict__assertNotEqualassertEqualr   )r   ZNUMTASKSr'   r(   Z
numrunningthreadsitr   r   r	   test_various_opsm   s4    




zThreadTests.test_various_opsc                    sx   t  }| |jd u  t| t|  fdd}t   g t|d  	  | d d u  t j
d = d S )Nc                     s0   t  } | j t|  t|     d S r   )r$   current_threadr:   r6   strrB   set)rK   r,   r6   r   r	   f   s
    z9ThreadTests.test_ident_of_no_threading_threads.<locals>.fr   r   )r$   rM   r>   r6   rN   rB   Eventthreadstart_new_threadwait_active)r   rK   rQ   r   rP   r	   "test_ident_of_no_threading_threads   s    z.ThreadTests.test_ident_of_no_threading_threadsc                 C   sT   t rtd ztd W n" tjy<   t r6td Y d S 0 |   td d S )Nzwith 256kB thread stack size...i   4platform does not support changing thread stack sizer   r.   r/   r$   
stack_sizerS   errorrL   r   r   r   r	   test_various_ops_small_stack   s    z(ThreadTests.test_various_ops_small_stackc                 C   sT   t rtd ztd W n" tjy<   t r6td Y d S 0 |   td d S )Nzwith 1MB thread stack size...i   rX   r   rY   r   r   r   r	   test_various_ops_large_stack   s    z(ThreadTests.test_various_ops_large_stackc                 C   s\   dd }t  }|  t||f}|  | |t j | t j| t j t j|= d S )Nc                 S   s   t   |   d S r   )r$   rM   release)r(   r   r   r	   rQ      s    z*ThreadTests.test_foreign_thread.<locals>.f)	r$   LockacquirerS   rT   ZassertInrV   ZassertIsInstance_DummyThread)r   rQ   r(   tidr   r   r	   test_foreign_thread   s    zThreadTests.test_foreign_threadc                    s`  zdd l }W n  ty,   tr&td Y d S 0 |jj}G dd dt | }t	 t	 G  fdddtj
}| }d|_|  trtd trtd	 ||d
|}| |d trtd   trtd | |j trtd |||j|}| |d tr&td jdd | |j trLtd |jr\|  d S )Nr   z2test_PyThreadState_SetAsyncExc can't import ctypesc                   @   s   e Zd ZdS )zAThreadTests.SKIP_test_PyThreadState_SetAsyncExc.<locals>.AsyncExcN)r   r    r!   r   r   r   r	   AsyncExc   s   rd   c                       s$   e Zd ZdZdZ fddZdS )z?ThreadTests.SKIP_test_PyThreadState_SetAsyncExc.<locals>.WorkerNFc                    sN   t  | _d| _z  td qW n   yH   d| _  Y n0 d S )NFg?T)rS   	get_identidfinishedrO   r0   r1   r   rd   Zworker_saw_exceptionZworker_startedr   r	   r3      s    
zCThreadTests.SKIP_test_PyThreadState_SetAsyncExc.<locals>.Worker.run)r   r    r!   rf   rg   r3   r   rh   r   r	   Worker   s   ri   Tz    started worker threadz     trying nonsensical thread idz,    waiting for worker thread to get startedz"    verifying worker hasn't exitedz2    attempting to raise asynch exception in workerr   z5    waiting for worker to say it caught the exceptionr5   )timeoutz    all OK -- joining worker)ctypesImportErrorr.   r/   	pythonapiZPyThreadState_SetAsyncExc	ExceptionZ	py_objectr$   rR   r%   r;   rC   Zc_longrH   rU   r>   rg   rf   r?   rD   )r   rl   Zset_async_exc	exceptionri   rK   resultr   rh   r	   #SKIP_test_PyThreadState_SetAsyncExc   sN    
z/ThreadTests.SKIP_test_PyThreadState_SetAsyncExcc                 C   s^   dd }t j}|t _z<t jdd d}| tj|j | |t jv d W |t _n|t _0 d S )Nc                  W   s   t  d S r   )rS   r[   )_argsr   r   r	   fail_new_thread   s    z7ThreadTests.test_limbo_cleanup.<locals>.fail_new_threadc                   S   s   d S r   r   r   r   r   r	   <lambda>%  r   z0ThreadTests.test_limbo_cleanup.<locals>.<lambda>targetz:Failed to cleanup _limbo map on failure of Thread.start().)	r$   _start_new_threadr%   assertRaisesrS   r[   rC   r>   _limbo)r   rt   rx   rK   r   r   r	   test_limbo_cleanup  s    zThreadTests.test_limbo_cleanupc              	   C   s|   z"dd l }t|d t|jd W n$ ttfyF   tr@td Y d S 0 ~dd l}|t	j
ddddt g}| |d	 d S )
Nr   rn   ZPyGILState_Ensurez6test_finalize_with_runnning_thread can't import ctypes-Wignore-ca  if 1:
%s
            import ctypes, sys, time
            try:
                import thread
            except ImportError:
                import _thread as thread # Py3

            # This lock is used as a simple event variable.
            ready = thread.allocate_lock()
            ready.acquire()

            # Module globals are cleared before __del__ is run
            # So we save the functions in class dict
            class C:
                ensure = ctypes.pythonapi.PyGILState_Ensure
                release = ctypes.pythonapi.PyGILState_Release
                def __del__(self):
                    state = self.ensure()
                    self.release(state)

            def waitingThread():
                x = C()
                ready.release()
                time.sleep(100)

            thread.start_new_thread(waitingThread, ())
            ready.acquire()  # Be sure the other thread is waiting.
            sys.exit(42)
            *   )rl   getattrrn   rm   AttributeErrorr.   r/   
subprocesscallsys
executablesetup_3rH   )r   rl   r   rcr   r   r	   test_finalize_runnning_thread-  s    
z)ThreadTests.test_finalize_runnning_threadhangsc                 C   sh   dd l }dt }|jtjddd|g|j|jd}| \}}| }|d}|d}| 	d| d S )	Nr   a  if 1:
%s
                import threading
                from time import sleep

                def child():
                    sleep(0.3)
                    # As a non-daemon thread we SHOULD wake up and nothing
                    # should be torn down yet
                    print("Woke up, sleep function is: %%s.%%s" %% (sleep.__module__, sleep.__name__))

                threading.Thread(target=child).start()
                raise SystemExit
        r|   r}   r~   )stdoutstderrzutf-8z,Woke up, sleep function is: gevent.hub.sleep)
r   setup_4Popenr   r   PIPEcommunicatestripdecoderH   )r   r   scriptpr   r   r   r   r	   test_join_nondaemon_on_shutdown]  s     

z+ThreadTests.test_join_nondaemon_on_shutdowngetcheckintervalzNeeds sys.getcheckintervalc              
   C   s   t j}dd l}|  |dt t }zjtddD ]P}t	|d  t j
dd d}|  |  | }| ||v d	||f  q8W t	| nt	| 0 W d    n1 s0    Y  d S )
Nr   r}   r   d      c                   S   s   d S r   r   r   r   r   r	   ru     r   z7ThreadTests.test_enumerate_after_join.<locals>.<lambda>rv   z&#1703448 triggered after %d trials: %s)r$   	enumeratewarningscatch_warningssimplefilterDeprecationWarningr   r   r   Zsetcheckintervalr%   rC   rD   r>   )r   enumr   Zold_intervalrJ   rK   lr   r   r	   test_enumerate_after_join  s     


z%ThreadTests.test_enumerate_after_joinpypy_version_infoc                 C   s   G dd dt }|dd}t|}|j  ~| j| dt|  d |dd}t|}|j  ~| j| dt|  d d S )Nc                   @   s   e Zd Zdd Zdd ZdS )zDThreadTests.test_no_refcycle_through_target.<locals>.RunSelfFunctionc                 S   s.   || _ tj| j| fd| id| _| j  d S )N_yet_another)rw   argskwargs)should_raiser$   r%   _runrS   rC   )r   r   r   r   r	   r     s    zMThreadTests.test_no_refcycle_through_target.<locals>.RunSelfFunction.__init__c                 S   s   | j r
td S r   )r   
SystemExit)r   Z
_other_refr   r   r   r	   r     s    zIThreadTests.test_no_refcycle_through_target.<locals>.RunSelfFunction._runN)r   r    r!   r   r   r   r   r   r	   RunSelfFunction  s   	r   F)r   z%d references still around)msgT)objectweakrefrefrS   rD   r=   r   getrefcount)r   r   Zcyclic_objectZweak_cyclic_objectZraising_cyclic_objectZweak_raising_cyclic_objectr   r   r	   test_no_refcycle_through_target  s&    







z+ThreadTests.test_no_refcycle_through_targetN)r   r    r!   rL   rW   r\   r]   rc   rr   r{   r   r   skipOnLibuvOnPyPyOnWinr   r   r<   r   r   r   r   r   r   r	   r4   h   s"   #G0
$


r4   c                   @   s@   e Zd Zdd Zeddd Zeddd Zd	d
 Z	dS )ThreadJoinOnShutdownc                 C   s   dt  | }dd l}|jtjddd|g|jd}| }|j 	dd}|j
  | |d	 | |d
d | |dd d S )Nzif 1:
%s
            import sys, os, time, threading
            # a thread, which waits for the main program to terminate
            def joiningfunc(mainthread):
                mainthread.join()
                print('end of thread')
        
r   r|   r}   r~   )r      r   s   end of main
end of thread
   s   interpreter was blockeds   Unexpected error)r   r   r   r   r   r   rU   r   readreplacecloserH   rG   )r   r   r   r   r   datar   r   r	   _run_and_join  s    	
z"ThreadJoinOnShutdown._run_and_joinr   c                 C   s   d}|  | d S )Nzif 1:
            import os
            t = threading.Thread(target=joiningfunc,
                                 args=(threading.current_thread(),))
            t.start()
            time.sleep(0.2)
            print('end of main')
            )r   )r   r   r   r   r	   test_1_join_on_shutdown  s    z,ThreadJoinOnShutdown.test_1_join_on_shutdownzSometimes randomly times outc                 C   s(   dd l }t|dsd S d}| | d S )Nr   forkaG  if 1:
            childpid = os.fork()
            if childpid != 0:
                os.waitpid(childpid, 0)
                sys.exit(0)

            t = threading.Thread(target=joiningfunc,
                                 args=(threading.current_thread(),))
            t.start()
            print('end of main')
            osr<   r   r   r   r   r   r   r	   test_2_join_in_forked_process  s
    
z2ThreadJoinOnShutdown.test_2_join_in_forked_processc                 C   s(   dd l }t|dsd S d}| | d S )Nr   r   a5  if 1:
            main_thread = threading.current_thread()
            def worker():
                threading._after_fork = lambda: None
                childpid = os.fork()
                if childpid != 0:
                    os.waitpid(childpid, 0)
                    sys.exit(0)

                t = threading.Thread(target=joiningfunc,
                                     args=(main_thread,))
                print('end of main')
                t.start()
                t.join() # Should not block: main_thread is already stopped

            w = threading.Thread(target=worker)
            w.start()
            import sys
            if sys.version_info[:2] >= (3, 7) or (sys.version_info[:2] >= (3, 5) and hasattr(sys, 'pypy_version_info') and sys.platform != 'darwin'):
                w.join()
            r   r   r   r   r	   !test_3_join_in_forked_from_thread  s
    
z6ThreadJoinOnShutdown.test_3_join_in_forked_from_threadN)
r   r    r!   r   r   r   r   ZskipOnPyPy3OnCIr   r   r   r   r   r	   r     s   

r   c                   @   s,   e Zd Zdd Zdd Zdd Zdd Zd	S )
ThreadingExceptionTestsc                 C   s"   t  }|  | t|j d S r   )r$   r%   rC   ry   RuntimeErrorr   Zthread_r   r   r	   test_start_thread_again4  s    z/ThreadingExceptionTests.test_start_thread_againc                 C   s   t  }| t|j d S r   )r$   rM   ry   r   rD   )r   rM   r   r   r	   test_joining_current_thread9  s    z3ThreadingExceptionTests.test_joining_current_threadc                 C   s   t  }| t|j d S r   )r$   r%   ry   r   rD   r   r   r   r	   test_joining_inactive_thread=  s    z4ThreadingExceptionTests.test_joining_inactive_threadc                 C   s&   t  }|  | tt|dd d S )Nr;   T)r$   r%   rC   ry   r   setattrr   r   r   r	   test_daemonize_active_threadA  s    z4ThreadingExceptionTests.test_daemonize_active_threadN)r   r    r!   r   r   r   r   r   r   r   r	   r   /  s   r   c                   @   s   e Zd ZeejZdS )	LockTestsN)r   r    r!   staticmethodr$   r_   locktyper   r   r   r	   r   G  s   r   c                   @   s   e Zd ZeejZdS )
RLockTestsN)r   r    r!   r   r$   r8   r   r   r   r   r	   r   K  s   r   c                   @   s   e Zd ZeejZdS )NativeRLockTestsN)r   r    r!   r   r$   ZNativeRLockr   r   r   r   r	   r   O  s   r   c                   @   s   e Zd ZeejZdS )
EventTestsN)r   r    r!   r   r$   rR   Z	eventtyper   r   r   r	   r   U  s   r   c                   @   s   e Zd ZeejZdS )ConditionAsRLockTestsN)r   r    r!   r   r$   	Conditionr   r   r   r   r	   r   Y  s   r   c                   @   s   e Zd ZeejZdS )ConditionTestsN)r   r    r!   r   r$   r   Zcondtyper   r   r   r	   r   ^  s   r   c                   @   s   e Zd ZeejZdS )SemaphoreTestsN)r   r    r!   r   r$   	Semaphoresemtyper   r   r   r	   r   b  s   r   c                   @   s   e Zd ZeejZdS )BoundedSemaphoreTestsN)r   r    r!   r   r$   r7   r   r   r   r   r	   r   f  s   r   __main__).
__future__r   Zgevent.testing.sixr   Zgevent.testingtestingr   Zsetup_execrD   splitr   r   r   r.   r-   r@   r   r$   rS   rm   _threadr0   r   r   Zgevent.testsr   r   r   r   r%   r"   ZTestCaser4   r   r   r   r   r   r   r   r   r   r   r   mainr   r   r   r	   <module>   sd      Wp
