Ë
    êmxi˜1  ã                   ó>  — 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ZddlZddlm	Z	 ddl
mZmZmZ ddlmZ ddlmZ ddlmZ ddlZddlmZmZmZ ej0                  rdd	lmZ ej4                  Zd
efd„Zdd„Zda	 ddee   dee   d
efd„Zd
ee   fd„Z  G d„ d«      Z!y)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                  óÚ   — t         €y	 t        j                  «       S # t        $ r Y nw xY w	 t        j                  d«      S # t
        t        f$ r Y nw xY wt        j                  d«       y)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© ó    úF/home/htdocs/ttos/venv/lib/python3.12/site-packages/tornado/process.pyr   r   1   sm   € äÐØðÜ×(Ñ(Ó*Ð*øÜò ÙðúðÜ�z‰zÐ/Ó0Ð0øÜœJÐ'ò Ùðúä‡M�MÐEÔFØs   ‰ �	)¨)­A ÁAÁAc                  ó.  — dt         j                  vry dd l} 	 t        t	        t        j                  d«      «      d«      }| j                  |«       y # t        $ r8 t        t        j                  «       dz  «      t        j                  «       z  }Y ŒRw xY w)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 Á>BÂBÚnum_processesÚmax_restartsc                 ó(  ‡	— t         j                  dk(  rt        d«      ‚|€d}t        �J ‚| �| dk  r
t	        «       } t        j                  d| «       i Š	dt        dt        t           fˆ	fd	„}t        | «      D ]  } ||«      }|€Œ|c S  d}‰	rît        j                  «       \  }}|‰	vrŒ‰	j                  |«      }t        j                  |«      r,t        j                  d
||t        j                  |«      «       n\t        j                   |«      dk7  r,t        j                  d||t        j                   |«      «       nt        j                  d||«       ŒÌ|dz  }||kD  rt#        d«      ‚ ||«      }|�|S ‰	rŒît        j$                  d«       y)aq  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                 ó^   •— t        j                  «       }|dk(  rt        «        | a| S | ‰|<   y ©Nr   )r   Úforkr'   Ú_task_id)r-   ÚpidÚchildrens     €r   Ústart_childz#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_processesrE   S   sŽ  ø€ ô< ‡|�|�wÒô Ð7Ó8Ð8ØÐØˆô ÐÐÐØÐ °Ò 2Ü!›ˆÜ‡L�LÐ(¨-Ô8Ø€Hð
”sð 
œx¬™}õ 
ô �=Ó!ò ˆÙ˜‹^ˆØ‰>ØŠIðð €LÙ
Ü—g‘g“i‰ˆˆVØ�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                  ó   — t         S )zpReturns the current task id, if any.

    Returns None if this process was not created by `fork_processes`.
    )r1   r   r   r   Útask_idrG   ³   s	   € ô €Or   c                   óÈ   — e Zd ZdZ e«       ZdZi Zdededdfd„Z	de
egdf   ddfd	„Zdd
eddfd„Zedd„«       Zedd„«       Zedd„«       Zededdfd„«       Zdeddfd„Zy)Ú
Subprocessa   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           	      óf  — t         j                  j                  «       | _        g }g }|j	                  d«      t
        j                  u rPt        j                  «       \  }}||d<   |j                  ||f«       |j                  |«       t        |«      | _        |j	                  d«      t
        j                  u rPt        j                  «       \  }}||d<   |j                  ||f«       |j                  |«       t        |«      | _        |j	                  d«      t
        j                  u rPt        j                  «       \  }	}
|
|d<   |j                  |	|
f«       |j                  |
«       t        |	«      | _        	 t        j                   |i |¤Ž| _        |D ]  }t        j$                  |«       Œ | j"                  j&                  | _        dD ]0  }t)        | |«      rŒt+        | |t-        | j"                  |«      «       Œ2 d | _        d | _        y #  |D ]  }t        j$                  |«       Œ ‚ xY w)NÚstdinÚstdoutÚstderr)rM   rN   rO   )r   ÚIOLoopÚcurrentÚio_loopÚgetrI   ÚSTREAMr   ÚpipeÚextendÚappendr   rM   rN   rO   Ú
subprocessÚPopenÚprocÚcloser2   ÚhasattrÚsetattrÚgetattrÚ_exit_callbackÚ
returncode)ÚselfrJ   rK   Úpipe_fdsÚto_closeÚin_rÚin_wÚout_rÚout_wÚerr_rÚerr_wÚfdÚattrs                r   Ú__init__zSubprocess.__init__×   sÕ  € Ü—}‘}×,Ñ,Ó.ˆŒð ˆØˆØ�:‰:�gÓ¤*×"3Ñ"3Ñ3ÜŸ™›‰JˆD�$Ø"ˆF�7‰OØ�O‰O˜T 4˜LÔ)Ø�O‰O˜DÔ!Ü% dÓ+ˆDŒJØ�:‰:�hÓ¤:×#4Ñ#4Ñ4ÜŸ7™7›9‰LˆE�5Ø$ˆF�8ÑØ�O‰O˜U E˜NÔ+Ø�O‰O˜EÔ"Ü& uÓ-ˆDŒKØ�:‰:�hÓ¤:×#4Ñ#4Ñ4ÜŸ7™7›9‰LˆE�5Ø$ˆF�8ÑØ�O‰O˜U E˜NÔ+Ø�O‰O˜EÔ"Ü& uÓ-ˆDŒKð	Ü"×(Ñ(¨$Ð9°&Ñ9ˆDŒIð
 ò 	ˆBÜ�H‰H�R�Lð	à—9‘9—=‘=ˆŒØ1ò 	>ˆDÜ˜4 Õ&Ü˜˜d¤G¨D¯I©I°tÓ$<Õ=ð	>ð #ˆÔØˆ�øð	Øò �Ü—‘˜•ðàús   Å<H ÈH0Úcallbackc                 ó²   — || _         t        j                  «        | t        j                  | j                  <   t        j                  | j                  «       y)a¦  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)r_   rI   Ú
initializeÚ_waitingr2   Ú_try_cleanup_process)ra   rm   s     r   Úset_exit_callbackzSubprocess.set_exit_callbackþ   s>   € ð" 'ˆÔÜ×ÑÔØ(,Œ
×Ñ˜DŸH™HÑ%Ü×'Ñ'¨¯©Õ1r   Úraise_errorzFuture[int]c                 ó^   ‡‡— t        «       Šdt        ddfˆˆfd„}| j                  |«       ‰S )a2  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                 óZ   •— | dk7  r‰rt        ‰t        | d«      «       y t        ‰| «       y )Nr   Úunknown)r   ÚCalledProcessErrorr   )ru   Úfuturers   s    €€r   rm   z*Subprocess.wait_for_exit.<locals>.callback(  s-   ø€ Ø�aŠx™Kä5ØÔ.¨s°IÓ>õô 3°6¸3Õ?r   )r   r"   rr   )ra   rs   rm   ry   s    ` @r   Úwait_for_exitzSubprocess.wait_for_exit  s7   ù€ ô$ “ˆð	@œ#ð 	@ $ö 	@ð 	×Ñ˜xÔ(Øˆr   c                 ó¨   — | j                   ryt        j                  «       }|j                  t        j
                  | j                  «       d| _         y)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   ro   zSubprocess.initialize4  s>   € ð ×ÒØÜ×%Ñ%Ó'ˆØ×Ñ¤§¡°·±Ô=ØˆÕr   c                 ó’   — | j                   syt        j                  «       }|j                  t        j
                  «       d| _         y)z Removes the ``SIGCHLD`` handler.NF)r|   r}   r~   Úremove_signal_handlerr€   r�   rƒ   s     r   ÚuninitializezSubprocess.uninitializeI  s8   € ð ×ÒØÜ×%Ñ%Ó'ˆØ×"Ñ"¤6§>¡>Ô2Ø ˆÕr   c                 óv   — t        | j                  j                  «       «      D ]  }| j                  |«       Œ y ©N)Úlistrp   Úkeysrq   )r„   r2   s     r   r‚   zSubprocess._cleanupR  s1   € ä˜Ÿ™×)Ñ)Ó+Ó,ò 	*ˆCØ×$Ñ$ SÕ)ñ	*r   r2   c                 ó  — 	 t        j                  |t         j                  «      \  }}|dk(  ry ||k(  sJ ‚| j                  j                  |«      }|j                  j                  |j                  |«       y # t        $ r Y y w xY wr/   )	r   ÚwaitpidÚWNOHANGÚChildProcessErrorrp   r:   rR   Úadd_callbackÚ_set_returncode)r„   r2   Úret_pidrC   Úsubprocs        r   rq   zSubprocess._try_cleanup_processW  sy   € ð	Ü Ÿj™j¨¬b¯j©jÓ9‰OˆG�Vð �aŠ<ØØ˜#Š~Ðˆ~Ø—,‘,×"Ñ" 3Ó'ˆØ�‰×$Ñ$ W×%<Ñ%<¸fÕEøô !ò 	Ùð	ús   ‚'A8 Á8	BÂBrC   c                 ó˜  — t         j                  dk(  rd| _        nbt        j                  |«      rt        j
                  |«       | _        n1t        j                  |«      sJ ‚t        j                  |«      | _        | j                  | j                  _        | j                  r&| j                  }d | _	         || j                  «       y y )Nr+   éÿÿÿÿ)
r    r5   r`   r   r;   r=   Ú	WIFEXITEDr>   rZ   r_   )ra   rC   rm   s      r   r’   zSubprocess._set_returncodec  s•   € Ü�<‰<˜7Ò"Ø ˆD�Oä�~‰~˜fÔ%Ü#%§;¡;¨vÓ#6Ð"6�•ä—|‘| FÔ+Ð+Ð+Ü"$§.¡.°Ó"8�”ð  $Ÿ™ˆ�	‰	ÔØ×ÒØ×*Ñ*ˆHØ"&ˆDÔÙ�T—_‘_Õ%ð r   )T©r   N)Ú__name__Ú
__module__Ú__qualname__Ú__doc__ÚobjectrT   r|   rp   r   rl   r   r"   rr   Úboolrz   Úclassmethodro   rˆ   r‚   rq   r’   r   r   r   rI   rI   ¼   sÜ   „ ññ* ‹X€Fà€LØ€Hð%˜cð %¨Sð %°Tó %ðN2¨(°C°5¸$°;Ñ*?ð 2ÀDó 2ñ,¨ð ¸ó ð@ ò ó ð ð( ò!ó ð!ð ò*ó ð*ð ð	F sð 	F¨tò 	Fó ð	Fð& cð &¨dô &r   rI   r˜   rŠ   )"rœ   r}   r   r   r€   rX   r    r$   Úbinasciir   Útornado.concurrentr   r   r   Útornador   Útornado.iostreamr   Útornado.logr	   Útypingr
   r   r   ÚTYPE_CHECKINGr   rx   r"   r   r'   r1   rE   rG   rI   r   r   r   ú<module>r§      sÁ   ðñ ó Û 	Û Û Û Û 
Û å ÷ñ õ
 Ý )Ý ã ß *Ñ *à	×ÒÝð  ×2Ñ2Ð ð�3ó ó ð €ð AEñ]Ø˜C‘=ð]Ø08¸±ð]àó]ð@�˜#‘ó ÷w&ò w&r   