ó
    Rì?g 1  ã                   óT  • S r SSKrSSKrSSKrSSKrSSKrSSKrSSKrSSKJ	r	  SSK
JrJrJr  SSKJr  SSKJr  SSKJr  SSKrSSKJrJrJr  \R0                  (       a  SS	KJr  \R4                  rS
\4S jrSS jrSq SS\\   S\\   S
\4S jjrS
\\   4S jr  " S S\!5      r"g)z„Utilities for working with multiple processes, including both forking
the server into multiple processes and managing subprocesses.
é    N)Úhexlify)ÚFutureÚ"future_set_result_unless_cancelledÚ%future_set_exception_unless_cancelled)Úioloop)ÚPipeIOStream)Úgen_log)ÚOptionalÚAnyÚCallable)ÚListÚreturnc                  óæ   • [         c  g [         R                  " 5       $ ! [         a     Of = f [        R                  " S5      $ ! [
        [        4 a     Of = f[        R                  " S5        g)z1Returns the number of processors on this machine.é   ÚSC_NPROCESSORS_CONFz1Could not detect number of processors; assuming 1)	ÚmultiprocessingÚ	cpu_countÚNotImplementedErrorÚosÚsysconfÚAttributeErrorÚ
ValueErrorr	   Úerror© ó    Ú1/usr/lib/python3/dist-packages/tornado/process.pyr   r   1   sm   € äÑØðÜ×(Ò(Ó*Ð*øÜó ÙðúðÜ�zŠzÐ/Ó0Ð0øÜœJÐ'ó Ùðúä‡M‚MÐEÔFØs   Š Ÿ
,«,°A ÁAÁAc                  ó:  • S[         R                  ;  a  g SS Kn  [        [	        [
        R                  " S5      5      S5      nU R                  U5        g ! [         a:    [        [        R                  " 5       S-  5      [
        R                  " 5       -  n NUf = f)NÚrandomr   é   iè  )ÚsysÚmodulesr   Úintr   r   Úurandomr   ÚtimeÚgetpidÚseed)r   r&   s     r   Ú_reseed_randomr'   A   sq   € Ø”s—{‘{Ó"ØÛð
5Ü”7œ2Ÿ:š: b›>Ó*¨BÓ/ˆð ‡K�K�Õøô ó 5Ü”4—9’9“; Ñ%Ó&¬¯ª«Ñ4Šð5ús   ›)A ÁABÂBÚnum_processesÚmax_restartsc                 ó|  ^	• [         R                  S:X  a  [        S5      eUc  Sn[        b   eU b  U S::  a
  [	        5       n [
        R                  " SU 5        0 m	S[        S[        [           4U	4S	 jjn[        U 5       H  nU" U5      nUc  M  Us  $    SnT	(       Ga  [        R                  " 5       u  pgUT	;  a  M'  T	R                  U5      n[        R                  " U5      (       a.  [
        R                  " S
UU[        R                  " U5      5        Oa[        R                   " U5      S:w  a.  [
        R                  " SUU[        R                   " U5      5        O[
        R                  " SXF5        Mâ  US-  nXQ:”  a  [#        S5      eU" U5      nUb  U$ T	(       a  GM  [         R$                  " S5        g)a!  Starts multiple worker processes.

If ``num_processes`` is None or <= 0, we detect the number of cores
available on this machine and fork that number of child
processes. If ``num_processes`` is given and > 0, we fork that
specific number of sub-processes.

Since we use processes and not threads, there is no shared memory
between any server code.

Note that multiple processes are not compatible with the autoreload
module (or the ``autoreload=True`` option to `tornado.web.Application`
which defaults to True when ``debug=True``).
When using multiple processes, no IOLoops can be created or
referenced until after the call to ``fork_processes``.

In each child process, ``fork_processes`` returns its *task id*, a
number between 0 and ``num_processes``.  Processes that exit
abnormally (due to a signal or non-zero exit status) are restarted
with the same id (up to ``max_restarts`` times).  In the parent
process, ``fork_processes`` calls ``sys.exit(0)`` after all child
processes have exited normally.

max_restarts defaults to 100.

Availability: Unix
Úwin32zfork not available on windowsNéd   r   zStarting %d processesÚir   c                 ób   >• [         R                  " 5       nUS:X  a  [        5         U qU $ U TU'   g ©Nr   )r   Úforkr'   Ú_task_id)r-   ÚpidÚchildrens     €r   Ústart_childÚ#fork_processes.<locals>.start_child   s1   ø€ Ü�gŠg‹iˆØ�!‹8äÔàˆHØˆHàˆH�S‰MØr   z1child %d (pid %d) killed by signal %d, restartingz3child %d (pid %d) exited with status %d, restartingz!child %d (pid %d) exited normallyr   z"Too many child restarts, giving up)r    ÚplatformÚ	Exceptionr1   r   r	   Úinfor"   r
   Úranger   ÚwaitÚpopÚWIFSIGNALEDÚwarningÚWTERMSIGÚWEXITSTATUSÚRuntimeErrorÚexit)
r(   r)   r4   r-   ÚidÚnum_restartsr2   ÚstatusÚnew_idr3   s
            @r   Úfork_processesrF   S   sˆ  ø€ ô< ‡|�|�wÓô Ð7Ó8Ð8ØÑØˆô ÑÐÐØÑ °Ó 2Ü!›ˆÜ‡L‚LÐ(¨-Ô8Ø€Hð
”sð 
œx¬™}÷ 
ô �=Ö!ˆÙ˜‹^ˆØ‹>ØŠIñ "ð €Lß
Ü—g’g“i‰ˆØ�hÓÙØ�\‰\˜#ÓˆÜ�>Š>˜&×!Ñ!Ü�OŠOØCØØÜ—’˜FÓ#õ	ô �^Š^˜FÓ# qÓ(Ü�OŠOØEØØÜ—’˜vÓ&õ	ô �LŠLÐ<¸bÔFÙØ˜ÑˆØÓ&ÜÐCÓDÐDÙ˜R“ˆØÑØˆM÷7 ‰(ô@ ‡H‚HˆQ…Kr   c                  ó   • [         $ )zhReturns the current task id, if any.

Returns None if this process was not created by `fork_processes`.
)r1   r   r   r   Útask_idrH   ³   s	   € ô €Or   c                   óâ   • \ rS rSrSr\" 5       rSr0 rS\	S\	SS4S jr
S	\\/S4   SS4S
 jrSS\SS4S jjr\SS j5       r\SS j5       r\SS j5       r\S\SS4S j5       rS\SS4S jrSrg)Ú
Subprocessé¼   aè  Wraps ``subprocess.Popen`` with IOStream support.

The constructor is the same as ``subprocess.Popen`` with the following
additions:

* ``stdin``, ``stdout``, and ``stderr`` may have the value
  ``tornado.process.Subprocess.STREAM``, which will make the corresponding
  attribute of the resulting Subprocess a `.PipeIOStream`. If this option
  is used, the caller is responsible for closing the streams when done
  with them.

The ``Subprocess.STREAM`` option and the ``set_exit_callback`` and
``wait_for_exit`` methods do not work on Windows. There is
therefore no reason to use this class instead of
``subprocess.Popen`` on that platform.

.. versionchanged:: 5.0
   The ``io_loop`` argument (deprecated since version 4.1) has been removed.

FÚargsÚkwargsr   Nc           	      óz  • [         R                  R                  5       U l        / n/ nUR	                  S5      [
        R                  L aN  [        R                  " 5       u  pVXRS'   UR                  XV45        UR                  U5        [        U5      U l        UR	                  S5      [
        R                  L aN  [        R                  " 5       u  pxX‚S'   UR                  Xx45        UR                  U5        [        U5      U l        UR	                  S5      [
        R                  L aN  [        R                  " 5       u  pšX¢S'   UR                  Xš45        UR                  U
5        [        U	5      U l         [        R                   " U0 UD6U l        U H  n[        R$                  " U5        M     U R"                  R&                  U l        S H5  n[)        X5      (       a  M  [+        X[-        U R"                  U5      5        M7     S U l        S U l        g !   U H  n[        R$                  " U5        M     e = f)NÚstdinÚstdoutÚstderr)rO   rP   rQ   )r   ÚIOLoopÚcurrentÚio_loopÚgetrJ   ÚSTREAMr   ÚpipeÚextendÚappendr   rO   rP   rQ   Ú
subprocessÚPopenÚprocÚcloser2   ÚhasattrÚsetattrÚgetattrÚ_exit_callbackÚ
returncode)ÚselfrL   rM   Úpipe_fdsÚto_closeÚin_rÚin_wÚout_rÚout_wÚerr_rÚerr_wÚfdÚattrs                r   Ú__init__ÚSubprocess.__init__×   s³  € Ü—}‘}×,Ñ,Ó.ˆŒð ˆØˆØ�:‰:�gÓ¤*×"3Ñ"3Ò3ÜŸš›‰JˆDØ"�7‰OØ�O‰O˜T˜LÔ)Ø�O‰O˜DÔ!Ü% dÓ+ˆDŒJØ�:‰:�hÓ¤:×#4Ñ#4Ò4ÜŸ7š7›9‰LˆEØ$�8ÑØ�O‰O˜U˜NÔ+Ø�O‰O˜EÔ"Ü& uÓ-ˆDŒKØ�:‰:�hÓ¤:×#4Ñ#4Ò4ÜŸ7š7›9‰LˆEØ$�8ÑØ�O‰O˜U˜NÔ+Ø�O‰O˜EÔ"Ü& uÓ-ˆDŒKð	Ü"×(Ò(¨$Ð9°&Ñ9ˆDŒIó
 ˆBÜ�HŠH�RŽLñ à—9‘9—=‘=ˆŒÛ1ˆDÜ˜4×&Ó&Ü˜¤G¨D¯I©I°tÓ$<Ö=ñ 2ð #ˆÔØˆ�øð	Û�Ü—’˜–ñ àús   Å9H È"H:Úcallbackc                 ó°   • Xl         [        R                  5         U [        R                  U R                  '   [        R                  U R                  5        g)aN  Runs ``callback`` when this process exits.

The callback takes one argument, the return code of the process.

This method uses a ``SIGCHLD`` handler, which is a global setting
and may conflict if you have other libraries trying to handle the
same signal.  If you are using more than one ``IOLoop`` it may
be necessary to call `Subprocess.initialize` first to designate
one ``IOLoop`` to run the signal handlers.

In many cases a close callback on the stdout or stderr streams
can be used as an alternative to an exit callback if the
signal handler is causing a problem.

Availability: Unix
N)ra   rJ   Ú
initializeÚ_waitingr2   Ú_try_cleanup_process)rc   rp   s     r   Úset_exit_callbackÚSubprocess.set_exit_callbackþ   s<   € ð" 'ÔÜ×ÑÔØ(,Œ
×Ñ˜DŸH™HÑ%Ü×'Ñ'¨¯©Õ1r   Úraise_errorzFuture[int]c                 ób   ^^• [        5       mS[        SS4UU4S jjnU R                  U5        T$ )aâ  Returns a `.Future` which resolves when the process exits.

Usage::

    ret = yield proc.wait_for_exit()

This is a coroutine-friendly alternative to `set_exit_callback`
(and a replacement for the blocking `subprocess.Popen.wait`).

By default, raises `subprocess.CalledProcessError` if the process
has a non-zero exit status. Use ``wait_for_exit(raise_error=False)``
to suppress this behavior and return the exit status without raising.

.. versionadded:: 4.2

Availability: Unix
Úretr   Nc                 óf   >• U S:w  a  T(       a  [        T[        U S5      5        g [        TU 5        g )Nr   Úunknown)r   ÚCalledProcessErrorr   )ry   Úfuturerw   s    €€r   rp   Ú*Subprocess.wait_for_exit.<locals>.callback(  s-   ø€ Ø�a‹xžKä5ØÔ.¨s°IÓ>õô 3°6¸3Õ?r   )r   r"   ru   )rc   rw   rp   r}   s    ` @r   Úwait_for_exitÚSubprocess.wait_for_exit  s=   ù€ ô$ “ˆð	@œ#ð 	@ $÷ 	@ð 	@ð 	×Ñ˜xÔ(Øˆr   c                 ó´   • U R                   (       a  g[        R                  " 5       nUR                  [        R
                  U R                  5        SU l         g)a™  Initializes the ``SIGCHLD`` handler.

The signal handler is run on an `.IOLoop` to avoid locking issues.
Note that the `.IOLoop` used for signal handling need not be the
same one used by individual Subprocess objects (as long as the
``IOLoops`` are each running in separate threads).

.. versionchanged:: 5.0
   The ``io_loop`` argument (deprecated since version 4.1) has been
   removed.

Availability: Unix
NT)Ú_initializedÚasyncioÚget_event_loopÚadd_signal_handlerÚsignalÚSIGCHLDÚ_cleanup©ÚclsÚloops     r   rr   ÚSubprocess.initialize4  s>   € ð ××ØÜ×%Ò%Ó'ˆØ×Ñ¤§¡°·±Ô=ØˆÕr   c                 óž   • U R                   (       d  g[        R                  " 5       nUR                  [        R
                  5        SU l         g)z Removes the ``SIGCHLD`` handler.NF)r‚   rƒ   r„   Úremove_signal_handlerr†   r‡   r‰   s     r   ÚuninitializeÚSubprocess.uninitializeI  s8   € ð ××ØÜ×%Ò%Ó'ˆØ×"Ñ"¤6§>¡>Ô2Ø ˆÕr   c                 óz   • [        U R                  R                  5       5       H  nU R                  U5        M     g ©N)Úlistrs   Úkeysrt   )rŠ   r2   s     r   rˆ   ÚSubprocess._cleanupR  s,   € ä˜Ÿ™×)Ñ)Ó+Ö,ˆCØ×$Ñ$ SÖ)ò -r   r2   c                 ó  •  [         R                  " U[         R                  5      u  p#US:X  a  g X!:X  d   eU R                  R                  U5      nUR                  R                  UR                  U5        g ! [         a     g f = fr/   )	r   ÚwaitpidÚWNOHANGÚChildProcessErrorrs   r;   rT   Úadd_callbackÚ_set_returncode)rŠ   r2   Úret_pidrD   Úsubprocs        r   rt   ÚSubprocess._try_cleanup_processW  su   € ð	Ü Ÿjšj¨¬b¯j©jÓ9‰OˆGð �a‹<ØØ‹~Ðˆ~Ø—,‘,×"Ñ" 3Ó'ˆØ�‰×$Ñ$ W×%<Ñ%<¸fÕEøô !ó 	Ùð	ús   ‚'A9 Á9
BÂBrD   c                 óÀ  • [         R                  S:X  a  SU l        Op[        R                  " U5      (       a  [        R
                  " U5      * U l        O8[        R                  " U5      (       d   e[        R                  " U5      U l        U R                  U R                  l        U R                  (       a&  U R                  nS U l	        U" U R                  5        g g )Nr+   éÿÿÿÿ)
r    r6   rb   r   r<   r>   Ú	WIFEXITEDr?   r\   ra   )rc   rD   rp   s      r   r›   ÚSubprocess._set_returncodec  s›   € Ü�<‰<˜7Ó"Ø ˆD�Oä�~Š~˜f×%Ñ%Ü#%§;¢;¨vÓ#6Ð"6�•ä—|’| F×+Ñ+Ð+Ð+Ü"$§.¢.°Ó"8�”ð  $Ÿ™ˆ�	‰	ÔØ××Ø×*Ñ*ˆHØ"&ˆDÔÙ�T—_‘_Õ%ð r   )ra   rT   r2   r\   rb   rQ   rO   rP   )T©r   N)Ú__name__Ú
__module__Ú__qualname__Ú__firstlineno__Ú__doc__ÚobjectrV   r‚   rs   r   rn   r   r"   ru   Úboolr   Úclassmethodrr   r�   rˆ   rt   r›   Ú__static_attributes__r   r   r   rJ   rJ   ¼   sÜ   † ññ* ‹X€Fà€LØ€Hð%˜cð %¨Sð %°Tô %ðN2¨(°C°5¸$°;Ñ*?ð 2ÀDô 2ñ,¨ð ¸õ ð@ ó ó ð ð( ó!ó ð!ð ó*ó ð*ð ð	F sð 	F¨tó 	Fó ð	Fð& cð &¨d÷ &r   rJ   r£   r’   )#r¨   rƒ   r   r   r†   rZ   r    r$   Úbinasciir   Útornado.concurrentr   r   r   Útornador   Útornado.iostreamr   Útornado.logr	   Útypingr
   r   r   ÚTYPE_CHECKINGr   r|   r"   r   r'   r1   rF   rH   r©   rJ   r   r   r   Ú<module>r´      sÃ   ðñ ó Û 	Û Û Û Û 
Û å ÷ñ õ
 Ý )Ý ã ß *Ñ *à	××Ýð  ×2Ñ2Ð ð�3ô ô ð €ð AEñ]Ø˜C‘=ð]Ø08¸±ð]àõ]ð@�˜#‘ô ôw&�õ w&r   