Ë
    oj�V  ã                   óX  — d 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 ddl	m
Z
mZmZmZ ddlmZ  G d„ d«      Z ej"                  e«        G d„ d	ej$                  «      Z G d
„ dej$                  «      Z G d„ dej*                  «      Z G d„ d«      Z G d„ dej$                  «      Zy)z(
Tests for L{twisted.python.threadpool}
é    N)ÚTeamÚcreateMemoryWorker)ÚcontextÚfailureÚ
threadableÚ
threadpool)Úunittestc                   ó"   — e Zd ZdZd„ Zd„ ZdgZy)ÚSynchronizationr   c                 ó`   — || _         || _        t        j                  «       | _        g | _        y ©N)ÚNÚwaitingÚ	threadingÚLockÚlockÚruns)Úselfr   r   s      ú>/usr/lib/python3/dist-packages/twisted/test/test_threadpool.pyÚ__init__zSynchronization.__init__   s%   € ØˆŒØˆŒÜ—N‘NÓ$ˆŒ	Øˆ�	ó    c                 ó
  — | j                   j                  d«      rHt        | j                  «      dz  st	        j
                  d«       | j                   j                  «        n| xj                  dz  c_        | j                   j                  «        | j                  j                  d «       t        | j                  «      | j                  k(  r| j                  j                  «        | j                   j                  «        y )NFé   g-Cëâ6*?é   )r   ÚacquireÚlenr   ÚtimeÚsleepÚreleaseÚfailuresÚappendr   r   ©r   s    r   ÚrunzSynchronization.run   sª   € ð �9‰9×Ñ˜UÔ#Ü�t—y‘y“> AÒ%ô —
‘
˜6Ô"Ø�I‰I×ÑÕà�MŠM˜QÑ�Mð
 	�	‰	×ÑÔØ�	‰	×Ñ˜ÔÜˆt�y‰y‹>˜TŸV™VÒ#Ø�L‰L× Ñ Ô"Ø�	‰	×ÑÕr   r#   N)Ú__name__Ú
__module__Ú__qualname__r    r   r#   Úsynchronized© r   r   r   r      s   „ Ø€Hòòð0 �7�Lr   r   c                   ó„   — e Zd ZdZd„ Zd„ Zd„ Zd„ Zd„ Zd„ Z	d„ Z
d	„ Zd
„ Zd„ Zd„ Zd„ Zd„ Zd„ Zd„ Zd„ Zd„ Zd„ Zdd„Zy)ÚThreadPoolTestsz
    Test threadpools.
    c                  ó   — y)zD
        Return number of seconds to wait before giving up.
        r   r(   r"   s    r   Ú
getTimeoutzThreadPoolTests.getTimeout@   ó   € ð r   c                 óš   — t        d«      }|D ]*  }|j                  d«      r y t        j                  d«       Œ, | j	                  d«       y )Ni@B Fgñhãˆµøä>z%A long time passed without succeeding)Úranger   r   r   Úfail)r   r   ÚitemsÚis       r   Ú_waitForLockzThreadPoolTests._waitForLockF   sD   € Ü�g“ˆØò 	?ˆAØ�|‰|˜EÔ"ÙÜ�J‰J�tÕð	?ð
 �I‰IÐ=Õ>r   c                 ó    — t        j                  dd«      }| j                  |j                  d«       | j                  |j                  d«       y)zy
        L{ThreadPool.min} and L{ThreadPool.max} are set to the values passed to
        L{ThreadPool.__init__}.
        é   é   N)r   Ú
ThreadPoolÚassertEqualÚminÚmax©r   Úpools     r   Útest_attributeszThreadPoolTests.test_attributesO   s>   € ô
 ×$Ñ$ R¨Ó,ˆØ×Ñ˜Ÿ™ 2Ô&Ø×Ñ˜Ÿ™ 2Õ&r   c                 óæ  — t        j                  dd«      }|j                  «        | j                  |j                  «       | j                  t        |j                  «      d«       t        j                  dd«      }| j                  t        |j                  «      d«       |j                  «        | j                  |j                  «       | j                  t        |j                  «      d«       y)zV
        L{ThreadPool.start} creates the minimum number of threads specified.
        r   r   é   é
   N)r   r7   ÚstartÚ
addCleanupÚstopr8   r   Úthreadsr;   s     r   Ú
test_startzThreadPoolTests.test_startX   s¥   € ô ×$Ñ$ Q¨Ó*ˆØ�
‰
ŒØ�‰˜Ÿ	™	Ô"Ø×Ñœ˜TŸ\™\Ó*¨AÔ.ä×$Ñ$ Q¨Ó+ˆØ×Ñœ˜TŸ\™\Ó*¨AÔ.Ø�
‰
ŒØ�‰˜Ÿ	™	Ô"Ø×Ñœ˜TŸ\™\Ó*¨AÕ.r   c                 óÜ   — t        j                  dd«      }|j                  «        |j                  «        |j	                  d«       | j                  t        |j                  «      d«       y)z�
        L{ThreadPool.adjustPoolsize} only modifies the pool size and does not
        start new workers while the pool is not running.
        r   r   é   N)r   r7   rA   rC   ÚadjustPoolsizer8   r   rD   r;   s     r   Útest_adjustingWhenPoolStoppedz-ThreadPoolTests.test_adjustingWhenPoolStoppedg   sO   € ô
 ×$Ñ$ Q¨Ó*ˆØ�
‰
ŒØ�	‰	ŒØ×Ñ˜AÔØ×Ñœ˜TŸ\™\Ó*¨AÕ.r   c                 ó~  — t        j                  dd«      }|j                  «        | j                  |j                  «       | j                  |j                  g «       d„ } G d„ d«      } |«       }t        j                  |«      }t        j                  |«      }|j                  ||«       t        j                  «       }|j                  |j                  «       |j                  | j                  «       «       ~~t        j                   «        | j#                   |«       «       | j#                   |«       «       y)zü
        Test that creating threads in the threadpool with application-level
        objects as arguments doesn't results in those objects never being
        freed, with the thread maintaining a reference to them as long as it
        exists.
        r   r   c                  ó   — y r   r(   )Úargs    r   Úworkerz<ThreadPoolTests.test_threadCreationArguments.<locals>.worker�   s   € Ør   c                   ó   — e Zd Zy)ú:ThreadPoolTests.test_threadCreationArguments.<locals>.DumbN©r$   r%   r&   r(   r   r   ÚDumbrO   …   ó   „ Ør   rQ   N)r   r7   rA   rB   rC   r8   rD   ÚweakrefÚrefÚcallInThreadr   ÚEventÚsetÚwaitr,   ÚgcÚcollectÚassertIsNone)r   ÚtprM   rQ   ÚuniqueÚ	workerRefÚ	uniqueRefÚevents           r   Útest_threadCreationArgumentsz,ThreadPoolTests.test_threadCreationArgumentsr   sé   € ô ×"Ñ" 1 aÓ(ˆØ
�‰Œ
Ø�‰˜Ÿ™Ô ð 	×Ñ˜Ÿ™ RÔ(ò	÷	ñ 	ñ “ˆä—K‘K Ó'ˆ	Ü—K‘K Ó'ˆ	ð 	�‰˜ Ô'ô —‘Ó!ˆØ
�‰˜Ÿ	™	Ô"Ø�
‰
�4—?‘?Ó$Ô%àØÜ
�
‰
ŒØ×Ñ™)›+Ô&Ø×Ñ™)›+Õ&r   c                 óÐ  ‡ ‡‡‡‡	‡
‡‡— t        j                  dd«      }|j                  «        ‰ j                  |j                  «       ‰ j                  |j                  g «       i Š	t        j                  «       Št        j                  «       Šg Š
ˆˆˆ	ˆ
ˆ ˆˆfd„}ˆfd„} G d„ d«      Š ‰«       }t        j                  |«      }t        j                  |«      Št        j                  |«      Š|j                  ||||¬«       ~~‰j                  «        ‰j                  ‰ j                  «       «       t        j                   «        ‰ j#                   ‰«       «       ‰ j#                   ‰«       «       ~t        j                   «        ‰ j#                   |«       «       ‰ j#                   ‰
d   «       «       ‰ j                  t%        ‰	j'                  «       «      ddg«       y)	ze
        As C{test_threadCreationArguments} above, but for
        callInThreadWithCallback.
        r   r   c                 óü   •— t        j                  «        ‰j                  ‰j                  «       «        ‰«       ‰d<    ‰«       ‰d<   ‰j	                  «        ‰j                  t        j                  |«      «       y )Nr^   r_   )rY   rZ   rX   r,   rW   r!   rS   rT   )	ÚsuccessÚresultÚonResultDoneÚonResultWaitÚrefdictÚ	resultRefr   r_   r^   s	     €€€€€€€r   ÚonResultzVThreadPoolTests.test_threadCreationArgumentsCallInThreadWithCallback.<locals>.onResult²   s^   ø€ ô �J‰JŒLØ×Ñ˜dŸo™oÓ/Ô0Ù#,£;ˆG�KÑ Ù#,£;ˆG�KÑ Ø×ÑÔØ×ÑœWŸ[™[¨Ó0Õ1r   c                 ó   •—  ‰«       S r   r(   )rL   ÚtestrQ   s     €r   rM   zTThreadPoolTests.test_threadCreationArgumentsCallInThreadWithCallback.<locals>.worker½   s
   ø€ Ù“6ˆMr   c                   ó   — e Zd Zy)úRThreadPoolTests.test_threadCreationArgumentsCallInThreadWithCallback.<locals>.DumbNrP   r(   r   r   rQ   rn   Á   rR   r   rQ   )rl   N)r   r7   rA   rB   rC   r8   rD   r   rV   rS   rT   ÚcallInThreadWithCallbackrW   rX   r,   rY   rZ   r[   ÚlistÚvalues)r   r\   rj   rM   r]   ÚonResultRefrQ   rf   rg   rh   ri   r_   r^   s   `     @@@@@@@r   Ú4test_threadCreationArgumentsCallInThreadWithCallbackzDThreadPoolTests.test_threadCreationArgumentsCallInThreadWithCallbackœ   sw  ÿ€ ô ×"Ñ" 1 aÓ(ˆØ
�‰Œ
Ø�‰˜Ÿ™Ô ð 	×Ñ˜Ÿ™ RÔ(ð ˆä —‘Ó(ˆÜ —‘Ó(ˆàˆ	÷	2ò 	2ô	÷	ñ 	ñ “ˆä—k‘k (Ó+ˆÜ—K‘K Ó'ˆ	Ü—K‘K Ó'ˆ	ð 	×#Ñ# H¨f°fÀ6Ð#ÔJàØð 	×ÑÔà×Ñ˜$Ÿ/™/Ó+Ô,Ü
�
‰
Œà×Ñ™)›+Ô&Ø×Ñ™)›+Ô&ð Ü
�
‰
ŒØ×Ñ™+›-Ô(Ø×Ñ˜,˜) A™,›.Ô)ð 	×Ñœ˜gŸn™nÓ.Ó/°$¸°Õ>r   c                 ó`  — t        j                  dd«      }| j                  |j                  d«       | j                  |j                  d«       t        j                  t        j                  |«      «      }| j                  |j                  d«       | j                  |j                  d«       y)z…
        Threadpools can be pickled and unpickled, which should preserve the
        number of threads and other parameters.
        é   é   N)r   r7   r8   r9   r:   ÚpickleÚloadsÚdumps)r   r<   Úcopys      r   Útest_persistencez ThreadPoolTests.test_persistenceæ   s   € ô
 ×$Ñ$ Q¨Ó+ˆà×Ñ˜Ÿ™ 1Ô%Ø×Ñ˜Ÿ™ 2Ô&ô �|‰|œFŸL™L¨Ó.Ó/ˆà×Ñ˜Ÿ™ 1Ô%Ø×Ñ˜Ÿ™ 2Õ&r   c                 óŽ  — d}t        j                  «       }|j                  «        | j                  |j                  «       t        j                  «       }|j                  «        t        ||«      }t        |«      D ]  } |||«       Œ | j                  |«       | j                  |j                  d|j                  › d�«       y)z 
        Test synchronization of calls made with C{method}, which should be
        one of the mechanisms of the threadpool to execute work in threads.
        r@   zrun() re-entered z timesN)r   r7   rA   rB   rC   r   r   r   r   r/   r3   ÚassertFalser    )r   Úmethodr   r\   r   Úactorr2   s          r   Ú_threadpoolTestzThreadPoolTests._threadpoolTestö   s¢   € ð ˆä×"Ñ"Ó$ˆØ
�‰Œ
Ø�‰˜Ÿ™Ô ä—.‘.Ó"ˆØ�‰ÔÜ  7Ó+ˆä�q“ò 	ˆAÙ�2�uÕð	ð 	×Ñ˜'Ô"à×Ñ˜Ÿ™Ð+<¸U¿^¹^Ð<LÈFÐ)SÕTr   c                 ó&   — | j                  d„ «      S )z?
        Call C{_threadpoolTest} with C{callInThread}.
        c                 ó8   — | j                  |j                  «      S r   )rU   r#   )r\   r   s     r   ú<lambda>z3ThreadPoolTests.test_callInThread.<locals>.<lambda>  s   € °b·o±oÀeÇiÁiÓ6P€ r   )r€   r"   s    r   Útest_callInThreadz!ThreadPoolTests.test_callInThread  s   € ð ×#Ñ#Ñ$PÓQÐQr   c                 ó  ‡—  G d„ dt         «      Šˆfd„}t        j                  dd«      }|j                  |«       |j	                  «        |j                  «        | j                  ‰«      }| j                  t        |«      d«       y)zi
        L{ThreadPool.callInThread} logs exceptions raised by the callable it
        is passed.
        c                   ó   — e Zd Zy)ú<ThreadPoolTests.test_callInThreadException.<locals>.NewErrorNrP   r(   r   r   ÚNewErrorr‡     rR   r   rˆ   c                  ó   •—  ‰ «       ‚r   r(   ©rˆ   s   €r   Ú
raiseErrorz>ThreadPoolTests.test_callInThreadException.<locals>.raiseError  ó   ø€ Ù“*Ðr   r   r   N)	Ú	Exceptionr   r7   rU   rA   rC   ÚflushLoggedErrorsr8   r   )r   r‹   r\   Úerrorsrˆ   s       @r   Útest_callInThreadExceptionz*ThreadPoolTests.test_callInThreadException  sj   ø€ ô	”yô 	ô	ô ×"Ñ" 1 aÓ(ˆØ
�‰˜
Ô#Ø
�‰Œ
Ø
�‰Œ	à×'Ñ'¨Ó1ˆØ×Ñœ˜V› aÕ(r   c                 ó’  ‡‡— t        j                  «       Š‰j                  «        g Šˆˆfd„}t        j                  dd«      }|j                  |d„ «       |j                  «        	 | j                  ‰«       |j                  «        | j                  ‰d   «       | j                  ‰d   d«       y# |j                  «        w xY w)zÀ
        L{ThreadPool.callInThreadWithCallback} calls C{onResult} with a
        two-tuple of C{(True, result)} where C{result} is the value returned
        by the callable supplied.
        c                 ój   •— ‰j                  «        ‰j                  | «       ‰j                  |«       y r   ©r   r!   ©rd   re   ÚresultsÚwaiters     €€r   rj   z?ThreadPoolTests.test_callInThreadWithCallback.<locals>.onResult5  ó%   ø€ Ø�N‰NÔØ�N‰N˜7Ô#Ø�N‰N˜6Õ"r   r   r   c                   ó   — y)Nrl   r(   r(   r   r   rƒ   z?ThreadPoolTests.test_callInThreadWithCallback.<locals>.<lambda>;  ó   � r   rl   N)r   r   r   r   r7   ro   rA   r3   rC   Ú
assertTruer8   )r   rj   r\   r•   r–   s      @@r   Útest_callInThreadWithCallbackz-ThreadPoolTests.test_callInThreadWithCallback*  sŸ   ù€ ô —‘Ó!ˆØ�‰Ôàˆõ	#ô
 ×"Ñ" 1 aÓ(ˆØ
×#Ñ# H©nÔ=Ø
�‰Œ
ð	Ø×Ñ˜fÔ%à�G‰GŒIà�‰˜ ™
Ô#Ø×Ñ˜ ™ VÕ,øð �G‰G�Iús   Á)B4 Â4Cc                 ó&  ‡‡‡—  G d„ dt         «      Šˆfd„}t        j                  «       Š‰j                  «        g Šˆˆfd„}t	        j
                  dd«      }|j                  ||«       |j                  «        	 | j                  ‰«       |j                  «        | j                  ‰d   «       | j                  ‰d   t        j                  «       | j                  t        ‰d   j                   ‰«      «       y# |j                  «        w xY w)zÍ
        L{ThreadPool.callInThreadWithCallback} calls C{onResult} with a
        two-tuple of C{(False, failure)} where C{failure} represents the
        exception raised by the callable supplied.
        c                   ó   — e Zd Zy)úRThreadPoolTests.test_callInThreadWithCallbackExceptionInCallback.<locals>.NewErrorNrP   r(   r   r   rˆ   rž   M  rR   r   rˆ   c                  ó   •—  ‰ «       ‚r   r(   rŠ   s   €r   r‹   zTThreadPoolTests.test_callInThreadWithCallbackExceptionInCallback.<locals>.raiseErrorP  rŒ   r   c                 ój   •— ‰j                  «        ‰j                  | «       ‰j                  |«       y r   r“   r”   s     €€r   rj   zRThreadPoolTests.test_callInThreadWithCallbackExceptionInCallback.<locals>.onResultX  r—   r   r   r   N)r�   r   r   r   r   r7   ro   rA   r3   rC   r}   ÚassertIsInstancer   ÚFailurerš   Ú
issubclassÚtype)r   r‹   rj   r\   rˆ   r•   r–   s       @@@r   Ú0test_callInThreadWithCallbackExceptionInCallbackz@ThreadPoolTests.test_callInThreadWithCallbackExceptionInCallbackF  sÑ   ú€ ô	”yô 	ô	ô —‘Ó!ˆØ�‰Ôàˆõ	#ô
 ×"Ñ" 1 aÓ(ˆØ
×#Ñ# H¨jÔ9Ø
�‰Œ
ð	Ø×Ñ˜fÔ%à�G‰GŒIà×Ñ˜ ™Ô$Ø×Ñ˜g a™j¬'¯/©/Ô:Ø�‰œ
 7¨1¡:§?¡?°HÓ=Õ>øð	 �G‰G�Iús   Á=C> Ã>Dc                 ó<  ‡‡—  G d„ dt         «      Št        j                  «       }|j                  «        g Šˆˆfd„}t	        j
                  dd«      }|j                  |d„ «       |j                  |j                  «       |j                  «        	 | j                  |«       |j                  «        | j                  ‰«      }| j                  t        |«      d«       | j                  ‰d   «       | j!                  ‰d   «       y# |j                  «        w xY w)zj
        L{ThreadPool.callInThreadWithCallback} logs the exception raised by
        C{onResult}.
        c                   ó   — e Zd Zy)úRThreadPoolTests.test_callInThreadWithCallbackExceptionInOnResult.<locals>.NewErrorNrP   r(   r   r   rˆ   r¨   p  rR   r   rˆ   c                 óV   •— ‰j                  | «       ‰j                  |«        ‰«       ‚r   )r!   )rd   re   rˆ   r•   s     €€r   rj   zRThreadPoolTests.test_callInThreadWithCallbackExceptionInOnResult.<locals>.onResultx  s#   ø€ Ø�N‰N˜7Ô#Ø�N‰N˜6Ô"Ù“*Ðr   r   r   c                   ó   — y r   r(   r(   r   r   rƒ   zRThreadPoolTests.test_callInThreadWithCallbackExceptionInOnResult.<locals>.<lambda>~  r™   r   N)r�   r   r   r   r   r7   ro   rU   r   rA   r3   rC   rŽ   r8   r   rš   r[   )r   r–   rj   r\   r�   rˆ   r•   s        @@r   Ú0test_callInThreadWithCallbackExceptionInOnResultz@ThreadPoolTests.test_callInThreadWithCallbackExceptionInOnResultj  sÝ   ù€ ô	”yô 	ô —‘Ó!ˆØ�‰Ôàˆõ	ô
 ×"Ñ" 1 aÓ(ˆØ
×#Ñ# H©lÔ;Ø
�‰˜Ÿ™Ô'Ø
�‰Œ
ð	Ø×Ñ˜fÔ%à�G‰GŒIà×'Ñ'¨Ó1ˆØ×Ñœ˜V› aÔ(à�‰˜ ™
Ô#Ø×Ñ˜' !™*Õ%øð �G‰G�Iús   ÂD	 Ä	Dc                 ó”  ‡‡— g Št        j                  «       Šˆˆfd„}ˆfd„}t        j                  dd«      }|j	                  ||«       |j                  «        | j                  |j                  «       ‰j                  | j                  «       «       | j                  t        ‰«      d«       | j                  ‰d   ‰d   «       y)z�
        L{ThreadPool.callInThreadWithCallback} calls the function it is
        given and the C{onResult} callback in the same thread.
        c                 ó€   •— ‰j                  t        j                  «       j                  «       ‰j	                  «        y r   )r!   r   Úcurrent_threadÚidentrW   )rd   re   r`   Ú	threadIdss     €€r   rj   z5ThreadPoolTests.test_callbackThread.<locals>.onResult–  s)   ø€ Ø×ÑœY×5Ñ5Ó7×=Ñ=Ô>Ø�I‰I�Kr   c                  ó`   •— ‰ j                  t        j                  «       j                  «       y r   )r!   r   r®   r¯   )r°   s   €r   Úfuncz1ThreadPoolTests.test_callbackThread.<locals>.funcš  s    ø€ Ø×ÑœY×5Ñ5Ó7×=Ñ=Õ>r   r   r   rG   N)r   rV   r   r7   ro   rA   rB   rC   rX   r,   r8   r   )r   rj   r²   r\   r`   r°   s       @@r   Útest_callbackThreadz#ThreadPoolTests.test_callbackThread�  sœ   ù€ ð
 ˆ	ä—‘Ó!ˆõ	ô	?ô ×"Ñ" 1 aÓ(ˆØ
×#Ñ# H¨dÔ3Ø
�‰Œ
Ø�‰˜Ÿ™Ô à�
‰
�4—?‘?Ó$Ô%Ø×Ñœ˜Y›¨Ô+Ø×Ñ˜ 1™ y°¡|Õ4r   c                 ó  ‡‡— t         j                  j                  «       j                  d   }d|d<   g Št	        j
                  «       Šˆˆfd„}ˆfd„}t        j                  dd«      }|j                  ||«       |j                  «        | j                  |j                  «       ‰j                  | j                  «       «       | j                  t        ‰«      d«       | j                  |‰d   «       | j                  |‰d   «       y	)
z±
        The context L{ThreadPool.callInThreadWithCallback} is invoked in is
        shared by the context the callable and C{onResult} callback are
        invoked in.
        éÿÿÿÿzthis must be presentÚtestingc                 óž   •— t         j                  j                  «       j                  d   }‰j	                  |«       ‰j                  «        y ©Nrµ   )r   ÚtheContextTrackerÚcurrentContextÚcontextsr!   rW   )rd   re   Úctxr»   r`   s      €€r   rj   z6ThreadPoolTests.test_callbackContext.<locals>.onResult³  s7   ø€ Ü×+Ñ+×:Ñ:Ó<×EÑEÀbÑIˆCØ�O‰O˜CÔ Ø�I‰I�Kr   c                  ó~   •— t         j                  j                  «       j                  d   } ‰j	                  | «       y r¸   )r   r¹   rº   r»   r!   )r¼   r»   s    €r   r²   z2ThreadPoolTests.test_callbackContext.<locals>.func¸  s.   ø€ Ü×+Ñ+×:Ñ:Ó<×EÑEÀbÑIˆCØ�O‰O˜CÕ r   r   r   rG   N)r   r¹   rº   r»   r   rV   r   r7   ro   rA   rB   rC   rX   r,   r8   r   )r   Úmyctxrj   r²   r\   r»   r`   s        @@r   Útest_callbackContextz$ThreadPoolTests.test_callbackContext¦  sÕ   ù€ ô ×)Ñ)×8Ñ8Ó:×CÑCÀBÑGˆØ1ˆˆiÑàˆä—‘Ó!ˆõ	ô
	!ô ×"Ñ" 1 aÓ(ˆØ
×#Ñ# H¨dÔ3Ø
�‰Œ
Ø�‰˜Ÿ™Ô à�
‰
�4—?‘?Ó$Ô%à×Ñœ˜X›¨Ô*Ø×Ñ˜ ¨¡Ô,Ø×Ñ˜ ¨¡Õ,r   c                 ó<  — t        j                  «       }|j                  «        t        j                  dd«      }|j                  |j                  «       |j                  «        	 | j                  |«       |j                  «        y# |j                  «        w xY w)zÃ
        Work added to the threadpool before its start should be executed once
        the threadpool is started: this is ensured by trying to release a lock
        previously acquired.
        r   r   N)
r   r   r   r   r7   rU   r   rA   r3   rC   )r   r–   r\   s      r   Útest_existingWorkz!ThreadPoolTests.test_existingWorkÇ  sk   € ô —‘Ó!ˆØ�‰Ôä×"Ñ" 1 aÓ(ˆØ
�‰˜Ÿ™Ô'Ø
�‰Œ
ð	Ø×Ñ˜fÔ%à�G‰G�IøˆB�G‰G�Iús   Á'B	 Â	Bc                 óö  ‡‡— t        j                  dd«      }|j                  «        | j                  |j                  «       | j                  |j                  d«       | j                  t        |j                  «      d«       | j                  t        |j                  «      d«       t        j                  «       Št        j                  «       Šˆˆfd„}|j                  |«       ‰j                  d«       | j                  |j                  d«       | j                  t        |j                  «      d«       | j                  t        |j                  «      d«       ‰j                  «        t        |j                  «      s+t        j                   d«       t        |j                  «      sŒ+| j                  t        |j                  «      d«       | j                  t        |j                  «      d«       y)z{
        As the worker receives and completes work, it transitions between
        the working and waiting states.
        r   r   c                  óH   •— ‰j                  «        ‰ j                  d«       y )Nr@   )rW   rX   )ÚthreadFinishÚthreadWorkings   €€r   Ú_threadz;ThreadPoolTests.test_workerStateTransition.<locals>._threadë  s   ø€ Ø×ÑÔØ×Ñ˜bÕ!r   r@   gü©ñÒMb@?N)r   r7   rA   rB   rC   r8   Úworkersr   ÚwaitersÚworkingr   rV   rU   rX   rW   r   r   )r   r<   rÆ   rÄ   rÅ   s      @@r   Útest_workerStateTransitionz*ThreadPoolTests.test_workerStateTransitionÙ  sc  ù€ ô
 ×$Ñ$ Q¨Ó*ˆØ�
‰
ŒØ�‰˜Ÿ	™	Ô"ð 	×Ñ˜Ÿ™ qÔ)Ø×Ñœ˜TŸ\™\Ó*¨AÔ.Ø×Ñœ˜TŸ\™\Ó*¨AÔ.ô "Ÿ™Ó)ˆÜ —‘Ó(ˆõ	"ð 	×Ñ˜'Ô"Ø×Ñ˜2ÔØ×Ñ˜Ÿ™ qÔ)Ø×Ñœ˜TŸ\™\Ó*¨AÔ.Ø×Ñœ˜TŸ\™\Ó*¨AÔ.ð 	×ÑÔÜ�d—l‘lÔ#Ü�J‰J�vÔô �d—l‘lÕ#ð 	×Ñœ˜TŸ\™\Ó*¨AÔ.Ø×Ñœ˜TŸ\™\Ó*¨AÕ.r   Nc                 ó„   — t        j                  dd«      }| j                  |j                  j	                  «       d«       y)zB
        There is a property '_queue' for legacy purposes
        r   r   N)r   r7   r8   Ú_queueÚqsizer;   s     r   Útest_qzThreadPoolTests.test_qþ  s3   € ô ×$Ñ$ Q¨Ó*ˆØ×Ñ˜Ÿ™×*Ñ*Ó,¨aÕ0r   )ÚreturnN)r$   r%   r&   Ú__doc__r,   r3   r=   rE   rI   ra   rs   r{   r€   r„   r�   r›   r¥   r«   r³   r¿   rÁ   rÊ   rÎ   r(   r   r   r*   r*   ;   so   „ ñòò?ò'ò/ò	/ò('òTH?òT'ò Uò4Rò)ò(-ò8"?òH!&òF5ò2-òBò$#/ôJ1r   r*   c                   ó   — e Zd Zd„ Zd„ Zd„ Zy)ÚRaceConditionTestsc                 óÎ   ‡ — t        j                  dd«      ‰ _         t        j                  «       ‰ _        ‰ j                   j                  «        ˆ fd„}‰ j                  |«       y )Nr   r@   c                  ó>   •— ‰ j                   j                  «        ‰ ` y r   )r   rC   r"   s   €r   Údonez&RaceConditionTests.setUp.<locals>.done  s   ø€ Ø�O‰O× Ñ Ô"Ø‘r   )r   r7   r   rV   r`   rA   rB   )r   rÕ   s   ` r   ÚsetUpzRaceConditionTests.setUp  sH   ø€ Ü$×/Ñ/°°2Ó6ˆŒÜ—_‘_Ó&ˆŒ
Ø�‰×ÑÔô	 ð 	�‰˜Õr   c                  ó   — y)z=
        A reasonable number of seconds to time out.
        r   r(   r"   s    r   r,   zRaceConditionTests.getTimeout  r-   r   c                 óŠ  — | j                  «       }| j                  j                  | j                  j                  «       | j                  j                  |«       | j                  j                  «        t        d«      D ]1  }| j                  j                  | j                  j
                  «       Œ3 | j                  j                  | j                  j                  «       | j                  j                  |«       | j                  j                  «       s,| j                  j	                  «        | j                  d«       yy)a�  
        If multiple threads are waiting on an event (via blocking on something
        in a callable passed to L{threadpool.ThreadPool.callInThread}), and
        there is spare capacity in the threadpool, sending another callable
        which will cause those to un-block to
        L{threadpool.ThreadPool.callInThread} will reliably run that callable
        and un-block the blocked threads promptly.

        @note: This is not really a unit test, it is a stress-test.  You may
            need to run it with C{trial -u} to fail reliably if there is a
            problem.  It is very hard to regression-test for this particular
            bug - one where the thread pool may consider itself as having
            "enough capacity" when it really needs to spin up a new thread if
            it possibly can - in a deterministic way, since the bug can only be
            provoked by subtle race conditions.
        r?   z9'set' did not run in thread; timed out waiting on 'wait'.N)
r,   r   rU   r`   rW   rX   Úclearr/   ÚisSetr0   )r   Útimeoutr2   s      r   Útest_synchronizationz'RaceConditionTests.test_synchronization  sÑ   € ð" —/‘/Ó#ˆØ�‰×$Ñ$ T§Z¡Z§^¡^Ô4Ø�
‰
�‰˜Ô Ø�
‰
×ÑÔÜ�q“ò 	:ˆAØ�O‰O×(Ñ(¨¯©¯©Õ9ð	:à�‰×$Ñ$ T§Z¡Z§^¡^Ô4Ø�
‰
�‰˜Ô Ø�z‰z×ÑÔ!Ø�J‰J�N‰NÔØ�I‰IÐQÕRð "r   N)r$   r%   r&   rÖ   r,   rÜ   r(   r   r   rÒ   rÒ     s   „ ò	òóSr   rÒ   c                   ó   — e Zd ZdZd„ Zd„ Zy)Ú
MemoryPoolz
    A deterministic threadpool that uses in-memory data structures to queue
    work rather than threads to execute work.
    c                 ót   — || _         || _        || _        t        j                  j
                  | g|¢­i |¤Ž y)aÄ  
        Initialize this L{MemoryPool} with a test case.

        @param coordinator: a worker used to coordinate work in the L{Team}
            underlying this threadpool.
        @type coordinator: L{twisted._threads.IExclusiveWorker}

        @param failTest: A 1-argument callable taking an exception and raising
            a test-failure exception.
        @type failTest: 1-argument callable taking (L{Failure}) and raising
            L{unittest.FailTest}.

        @param newWorker: a 0-argument callable that produces a new
            L{twisted._threads.IWorker} provider on each invocation.
        @type newWorker: 0-argument callable returning
            L{twisted._threads.IWorker}.
        N)Ú_coordinatorÚ	_failTestÚ
_newWorkerr   r7   r   )r   ÚcoordinatorÚfailTestÚ	newWorkerÚargsÚkwargss         r   r   zMemoryPool.__init__<  s8   € ð$ (ˆÔØ!ˆŒØ#ˆŒÜ×Ñ×&Ñ& tÐ=¨dÒ=°fÓ=r   c                 ó^   ‡ ‡‡— ˆˆ ˆfd„}t        ‰ j                  |‰ j                  ¬«      Š‰S )a§  
        Override testing hook to create a deterministic threadpool.

        @param currentLimit: A 1-argument callable which returns the current
            threadpool size limit.

        @param threadFactory: ignored in this invocation; a 0-argument callable
            that would produce a thread.

        @return: a L{Team} backed by the coordinator and worker passed to
            L{MemoryPool.__init__}.
        c                  óˆ   •— ‰j                  «       } | j                  | j                  z    ‰«       k\  ry ‰j                  «       S r   )Ú
statisticsÚbusyWorkerCountÚidleWorkerCountrâ   )ÚstatsÚcurrentLimitr   Úteams    €€€r   ÚrespectLimitz&MemoryPool._pool.<locals>.respectLimita  s<   ø€ ð —O‘OÓ%ˆEØ×%Ñ%¨×(=Ñ(=Ñ=Á,Ã.ÒPØØ—?‘?Ó$Ð$r   )rã   ÚcreateWorkerÚlogException)r   rà   rá   )r   rî   ÚthreadFactoryrð   rï   s   ``  @r   Ú_poolzMemoryPool._poolS  s.   ú€ ö	%ô Ø×)Ñ)Ø%ØŸ™ô
ˆð
 ˆr   N)r$   r%   r&   rÐ   r   rô   r(   r   r   rÞ   rÞ   6  s   „ ñò
>ó.r   rÞ   c                   ó   — e Zd ZdZd„ Zd„ Zy)Ú
PoolHelpera  
    A L{PoolHelper} constructs a L{threadpool.ThreadPool} that doesn't actually
    use threads, by using the internal interfaces in L{twisted._threads}.

    @ivar performCoordination: a 0-argument callable that will perform one unit
        of "coordination" - work involved in delegating work to other threads -
        and return L{True} if it did any work, L{False} otherwise.

    @ivar workers: the workers which represent the threads within the pool -
        the workers other than the coordinator.
    @type workers: L{list} of 2-tuple of (L{IWorker}, C{workPerformer}) where
        C{workPerformer} is a 0-argument callable like C{performCoordination}.

    @ivar threadpool: a modified L{threadpool.ThreadPool} to test.
    @type threadpool: L{MemoryPool}
    c                 ó‚   ‡ — t        «       \  }‰ _        g ‰ _        ˆ fd„}t        ||j                  |g|¢­i |¤Ž‰ _        y)zû
        Create a L{PoolHelper}.

        @param testCase: a test case attached to this helper.

        @type args: The arguments passed to a L{threadpool.ThreadPool}.

        @type kwargs: The arguments passed to a L{threadpool.ThreadPool}
        c                  ón   •— ‰ j                   j                  t        «       «       ‰ j                   d   d   S )Nrµ   r   )rÇ   r!   r   r"   s   €r   rå   z&PoolHelper.__init__.<locals>.newWorker‘  s-   ø€ Ø�L‰L×ÑÔ 2Ó 4Ô5Ø—<‘< Ñ# AÑ&Ð&r   N)r   ÚperformCoordinationrÇ   rÞ   r0   r   )r   ÚtestCaseræ   rç   rã   rå   s   `     r   r   zPoolHelper.__init__„  sK   ø€ ô 1CÓ0DÑ-ˆ�TÔ-ØˆŒô	'ô %Ø˜Ÿ™¨	ð
Ø48ò
Ø<Bñ
ˆ�r   c                 óJ   — | j                  «       r	 | j                  «       rŒyy)z‰
        Perform all currently scheduled "coordination", which is the work
        involved in delegating work to other threads.
        N)rù   r"   s    r   ÚperformAllCoordinationz!PoolHelper.performAllCoordination™  s!   € ð
 ×&Ñ&Ô(Øð ×&Ñ&×(r   N)r$   r%   r&   rÐ   r   rü   r(   r   r   rö   rö   r  s   „ ñò"
ó*r   rö   c                   ó   — e Zd ZdZd„ Zd„ Zy)ÚMemoryBackedTestszn
    Tests using L{PoolHelper} to deterministically test properties of the
    threadpool implementation.
    c                 óp  — t        | dd«      }d}t        |«      D ]  }|j                  j                  d„ «       Œ  |j	                  «        | j                  |j                  g «       |j                  j                  «        |j	                  «        | j                  t        |j                  «      |«       y)zÂ
        If a threadpool is told to do work before starting, then upon starting
        up, it will start enough workers to handle all of the enqueued work
        that it's been given.
        r   r@   r   c                   ó   — y r   r(   r(   r   r   rƒ   z;MemoryBackedTests.test_workBeforeStarting.<locals>.<lambda>±  r™   r   N)	rö   r/   r   rU   rü   r8   rÇ   rA   r   ©r   ÚhelperÚnÚxs       r   Útest_workBeforeStartingz)MemoryBackedTests.test_workBeforeStarting¨  s•   € ô ˜D ! RÓ(ˆØˆÜ�q“ò 	9ˆAØ×Ñ×*Ñ*©<Õ8ð	9à×%Ñ%Ô'Ø×Ñ˜Ÿ™¨Ô,Ø×Ñ×ÑÔ!Ø×%Ñ%Ô'Ø×Ñœ˜VŸ^™^Ó,¨aÕ0r   c                 ó˜  — t        | dd«      }d}t        |«      D ]  }|j                  j                  d„ «       Œ  |j	                  «        | j                  |j                  g «       |j                  j                  «        |j	                  «        | j                  t        |j                  «      |j                  j                  «       y)z°
        If the amount of work before starting exceeds the maximum number of
        threads allowed to the threadpool, only the maximum count will be
        started.
        r   r@   é2   c                   ó   — y r   r(   r(   r   r   rƒ   zBMemoryBackedTests.test_tooMuchWorkBeforeStarting.<locals>.<lambda>Á  r™   r   N)
rö   r/   r   rU   rü   r8   rÇ   rA   r   r:   r  s       r   Útest_tooMuchWorkBeforeStartingz0MemoryBackedTests.test_tooMuchWorkBeforeStarting¸  s¡   € ô ˜D ! RÓ(ˆØˆÜ�q“ò 	9ˆAØ×Ñ×*Ñ*©<Õ8ð	9à×%Ñ%Ô'Ø×Ñ˜Ÿ™¨Ô,Ø×Ñ×ÑÔ!Ø×%Ñ%Ô'Ø×Ñœ˜VŸ^™^Ó,¨f×.?Ñ.?×.CÑ.CÕDr   N)r$   r%   r&   rÐ   r  r	  r(   r   r   rþ   rþ   ¢  s   „ ñò
1ó Er   rþ   )rÐ   rY   rw   r   r   rS   Útwisted._threadsr   r   Útwisted.pythonr   r   r   r   Útwisted.trialr	   r   ÚsynchronizeÚSynchronousTestCaser*   rÒ   r7   rÞ   rö   rþ   r(   r   r   ú<module>r     s    ðñó
 
Û Û Û Û ç 5ß CÓ CÝ "÷!ñ !ðH €
× Ñ �Ô 'ôH1�h×2Ñ2ô H1ôV-S˜×5Ñ5ô -Sô`9�×&Ñ&ô 9÷x-ñ -ô`$E˜×4Ñ4õ $Er   