HEX
Server: Apache
System: Linux server2.voipitup.com.au 4.18.0-553.104.1.lve.el8.x86_64 #1 SMP Tue Feb 10 20:07:30 UTC 2026 x86_64
User: posscale (1027)
PHP: 8.2.29
Disabled: exec,passthru,shell_exec,system
Upload Files
File: //opt/saltstack/salt/lib/python3.10/site-packages/salt/utils/__pycache__/process.cpython-310.pyc
o

�N�g�@sdZddlZddlZddlZddlZddlZddlZddlZddlZddl	Z	ddl
Z	ddlZddlZddl
Z
ddlZddlZddlZddlZddlZddlZddlZddlZddlZddlZddlZddlmZddlmZe�e�Z dZ!zddl"Z"dZ!Wn	e#y�Ynwzddl$Z$dZ%Wne#y�dZ%YnwgZ&dd�Z'd4d	d
�Z(dd�Z)d
d�Z*dd�Z+dd�Z,d5dd�Z-dd�Z.dd�Z/dd�Z0dd�Z1dd�Z2d6d d!�Z3d"d#�Z4Gd$d%�d%�Z5Gd&d'�d'�Z6Gd(d)�d)e	j7�Z7Gd*d+�d+e7�Z8ej9d,d-��Z:Gd.d/�d/�Z;d0d1�Z<d2d3�Z=dS)7zE
Functions for daemonizing and otherwise modifying running processes
�N)�gen)�get_machine_identifierFTcCsJtr#t��}|���d�r|�dd�\}}t�|���d|���dSdS)z4
    Append "name" to the current process title
    �MainProcess�� N)�HAS_SETPROCTITLE�setproctitleZgetproctitle�strip�endswith�rsplit�rstrip)�name�current�_�r�F/opt/saltstack/salt/lib/python3.10/site-packages/salt/utils/process.py�appendproctitle6s�rc
Csxddl}zt��}|dkrt�|jjj�Wn"ty8}zt�	d|j
|�t�|jjj
�WYd}~nd}~wwt�d�t��t�d�zt��}|dkrXt�|jjj�Wn"ty{}zt�	d|j
|�t�|jjj
�WYd}~nd}~ww|r�|jj�dd��*}t|tj�t|tj�t|tj�t|d�t|d	�t|d
�Wd�dS1s�wYdSdS)z
    Daemonize a process
    rNzfork #1 failed: %s (%s)�/�zfork #2 failed: %s (%s)z	/dev/nullzr+r�)Zsalt.utils.crypt�os�fork�_exit�defaults�	exitcodes�EX_OK�OSError�log�error�errno�sys�exitZ
EX_GENERIC�chdir�setsid�umask�utils�files�fopen�dup2�stdin�stdout�stderr)Zredirect_out�salt�pid�excZdev_nullrrr�	daemonizeAsD���

���

"��r/cCs�t|t�r|}nz|��}Wntjyt�d|�YdSwt|t�r(|}nz|��}Wntjy?t�d|�YdSwt�||�dS)z�
    Duplicate file descriptor fd to fd2, closing the latter first if necessary.
    This method is similar to os.dup2 but ignores streams that do not have a
    supported fileno method.
    z!Unsupported operation on file: %rN)	�
isinstance�int�fileno�io�UnsupportedOperationr�warningrr()Zfile1Zfile2Zfno1Zfno2rrrr(ps"
�
�r(cCs>dtjdvr	dS|�dd�sdStj�d�rdStd�dS)z}
    Daemonize a module function process if multiprocessing is True and the
    process is not being called by salt-call
    z	salt-callrN�multiprocessingT�winF)r �argv�get�platform�
startswithr/)�optsrrr�daemonize_if�sr=cCs0tjd|gtjtjd�}|��|��}|dkS)�6
    Notify systemd that this process has started
    �systemd-notify�r*r+r)�
subprocess�Popen�PIPE�communicate�poll)�action�process�statusrrr�systemd_notify_call�s�rIcCs�zddl}WnTtyZtjj�d�rWtd�rWt�d�}|rW|�	d�r-d|dd���}zt
�
t
jt
j�}|�
|�|�d	�|��WYdStyVtd
�YYSwYdSw|j��rrz|j�d
�WStyqYdSwdS)r>rNr?z--bootedZ
NOTIFY_SOCKET�@�rsREADY=1z--readyTFzREADY=1)Zsystemd.daemon�ImportErrorr,r%�path�whichrIr�getenvr;�socket�AF_UNIX�
SOCK_DGRAM�connect�sendall�closer�daemonZbooted�notify�SystemError)ZsystemdZ
notify_socket�sockrrr�notify_systemd�s4




���
��rZcCsd|dur	t��}nt�|�sdSt�|�}z|��Wntjy&YdSw|j|��|�	�d�S)z�
    Gets basic info about a process.
    pid: None, or int: None will get the current process pid
    Return: None or Dict
    N)r-r
Z
start_time)
r�getpid�psutil�
pid_exists�ProcessrH�
NoSuchProcessr-r
Zcreate_time)r-Zraw_process_inforrr�get_process_info�s


��r`cCsNts
t�d|�dStj�|�}tj�|�s|rt�|�d}ztj	j
�|d��
}t�
|�}Wd�n1s8wYWntjjyOt�d|�Ynty]t�d|�Ynwt�}||krgdSt|t�rtt|�d�t�svd}t|t�r�|t|�d��kr�dStj	j
�|d	��}t�||�Wd�dS1s�wYdS)
z�
    Checks that no other live processes has this responsibility.
    If claiming the mantle of responsibility was successful True will be returned.
    file_name: str
    Return: bool
    �>Assuming no other Process has this responsibility! pidfile: %sTN�r�pidfile: %s is corrupted�pidfile: %s not foundr-F�w)�
HAS_PSUTILr�criticalrrM�dirname�isdir�makedirsr,r%r&r'�json�load�decoder�JSONDecodeErrorr�FileNotFoundError�infor`r0�dictr9r1�dump)�	file_nameZfile_directory_name�file_process_info�fileZthis_process_inforrr�claim_mantle_of_responsibility�sH	�
���
��
��rvcCs�ts
t�d|�dSztjj�|d��
}t�|�}Wd�n1s#wYWn!tj	j
y;t�d|�YdStyJt�
d|�YdSwt|t�rXt|�d�t�sZdS|t|d�krf|dSdS)z^
    Sees who has the mantle of responsibility
    file_name: str
    Return: None or int
    raNrbrcrdr-)rfrrgr,r%r&r'rkrlrmrnrrorpr0rqr9r1r`)rsrurtrrr�check_mantle_of_responsibilitys0����
��rwc

Cs�tj�|�}tj�|�s|rt�|�z#tjj�|d��}|�	t
t����Wd�n1s0wYWn	ty?Ynwt
�d|�tjj��rNdSddl}z|�|�}|d}|d}Wnttfy}tj�	d�|��t�tjjj�Ynwt��|kr�dSz	t�|||�Wn/ty�}z#d	�||�}	t
jd
|	dd�tj�	|	�d��t�|j�WYd}~nd}~wwt
�d
||�dS)z
    Save the pidfile
    zw+NzCreated pidfile: %sTrr�z>Failed to set the pid to user: {}. The user is not available.
z6Failed to set the ownership of PID file {} to user {}.z%s Traceback follows:��exc_info�
zChowned pidfile: %s to user: %s)rrMrhrirjr,r%r&r'�write�strr[rr�debugr:�
is_windows�pwd�getpwnam�KeyError�
IndexErrorr r+�formatr!rr�	EX_NOUSER�getuid�chownr)
�pidfile�userZpdirZofiler�Zpwnam�uid�gid�err�msgrrr�set_pidfile6sR
���
������r�cCstj�|�S)z5
    Determine if a pidfile has been written out
    )rrM�isfile)r�rrr�
check_pidfilegsr�c
Cs`z"tjj�|��}|����}Wd�n1swYt|�WSttt	fy/YdSw)z5
    Return the pid from a pidfile as an integer
    N���)
r,r%r&r'�readr	r1r�	TypeError�
ValueError)r�Zpdfr-rrr�get_pidfilens�
�r��
c	Cs�|sdSz4d}|��r6|��|d7}t�d�|��r/||kr/t�d|j�t�|jt	j
�|��sWdSWdSttfyDYdSw)z>
    Generic method for cleaning up multiprocessing procs
    Nrrg�������?z(Process did not die with terminate(): %s)
�is_alive�	terminate�time�sleeprrr-r�kill�signal�SIGKILL�AssertionError�AttributeError)�proc�
wait_for_killZwaitedrrr�
clean_proczs
��r�cCsHt|t�r	t|�}trt�|�Sz	t�|d�WdSty#YdSw)z@
    Use OS facilities to determine if a process is running
    rTF)	r0r}r1rfr\r]rr�r)r-rrr�
os_is_running�s

�r�c@s,eZdZdZd
dd�Zddd�Zdd	�ZdS)�
ThreadPoola%
    This is a very VERY basic threadpool implementation
    This was made instead of using multiprocessing ThreadPool because
    we want to set max queue size and we want to daemonize threads (neither
    is exposed in the stdlib version).

    Since there isn't much use for this class as of right now this implementation
    Only supports daemonized threads and will *not* return results

    TODO: if this is found to be more generally useful it would be nice to pull
    in the majority of code from upstream or from http://bit.ly/1wTeJtM
    NrcCsb|durt��}||_t�|�|_g|_t|�D]}tj	|j
d�}d|_|��|j�
|�qdS)N)�targetT)r6�	cpu_count�num_threads�queue�Queue�
_job_queueZ_workers�range�	threading�Thread�_thread_targetrV�start�append)�selfr�Z
queue_sizer�threadrrr�__init__�s�zThreadPool.__init__cCsH|durg}|duri}z|j�|||f�WdStjy#YdSw)NTF)r��
put_nowaitr��Full)r��func�args�kwargsrrr�
fire_async�s�zThreadPool.fire_asyncc
Cs�	zz|jjdd�\}}}|j��WntjyYWqwWn	ty)Yqwzt�d|||�||i|��WntyT}z
tj|dd�WYd}~nd}~wwq)NTr)�timeoutz4ThreadPool executing func: %s with args=%s kwargs=%sry)	r�r9�	task_doner��Emptyr�rr~�	Exception)r�r�r�r�r�rrrr��s2�������zThreadPool._thread_target�Nr�NN)�__name__�
__module__�__qualname__�__doc__r�r�r�rrrrr��s


r�c@sleZdZdZddd�Zddd�Zdd	�Zd
d�Zdd
�Ze	j
ddd��Zdd�Zdd�Z
dd�Zdd�ZdS)�ProcessManagerzD
    A class which will manage processes that should be running
    NrcCsHi|_||_|jdur|jj|_||_t��|_t�	tj
�|_d|_dS)NT)
�_process_mapr
�	__class__r�r�rr[�_pidr��	getsignal�SIGTERM�_sigterm_handler�_restart_processes)r�r
r�rrrr��s



zProcessManager.__init__cCs�|durg}|duri}t�|�r&t|tj�r&|p|j|d<||i|��}nt||||p.|jd�}|�t||�t|t	�rYt
tjtj
��|��Wd�n1sSwYn|��t�d|j|j�||||d�|j|j<|S)z�
        Create a processes and args + kwargs
        This will deterimine if it is a Process class, otherwise it assumes
        it is a function
        Nr
)r�r�r�r
zStarted '%s' with pid %s)�tgtr�r�r^)�inspectZisclass�
issubclassr6r^r��register_finalize_method�cleanup_finalize_processr0�SignalHandlingProcess�default_signalsr��SIGINTr�r�rr~r
r-r�)r�r�r�r�r
rGrrr�add_process�s0�

���zProcessManager.add_processcCs�|jdurdS|j|dj}|dkr't�d|j|d||j|dj�nt�d|j|d||j|dj�|j|d�d�|�|j|d|j|d|j|d	�|j|=dS)
zY
        Create new process (assuming this one is dead), then remove the old one
        FNr^rz7Process %s (%s) died with exit status %s, restarting...r�rr�r�)r�r��exitcoderrpr~�joinr�)r�r-r!rrr�restart_process"s.
���zProcessManager.restart_processcCs
d|_dS)NF)r��r�rrr�stop_restartingBs
zProcessManager.stop_restartingcCs�tjj��r|tjtjfvrdS|j��D]*}zt	�
||�Wqty?}z|jtj
tjfvr1�|j|=WYd}~qd}~wwdS�N)r,r%r:rr�r�r�r��copyrr�rr�ESRCH�EACCES)r�Zsignal_r-r.rrr�send_signal_to_processesEs����z'ProcessManager.send_signal_to_processesFc
cs��t�d�t��jdkrt|j�t�tj�tj	ur#t�tj|j
�t�tj�tj	ur4t�tj|j
�	t�d�z|�
�|rHt�d�Vnt�d�|jsSWdSWn#ty^YdStyw}z|jtjkrl�WYd}~dSd}~wwq5)z:
        Load and start all available api modules
        zProcess Manager starting!rTzProcess manager iterationr�N)rr~r6�current_processr
rr�r�r��SIG_DFL�_handle_signalsr��trace�check_childrenrr�r�r�rrZEINTR)r�Zasynchronousr.rrr�run`s6�



����zProcessManager.runcCsL|jdur"|j����D]\}}|d��s!t�d|�|�|�qdSdS)z)
        Check the children once
        Tr^zProcess restart of %sN)r�r�r��itemsr�rr�r�)r�r-�mappingrrrr��s

��zProcessManager.check_childrenc
Os�tjj��rHt��jdkrdStjj�t	j
d��'}|j��D]\}}t
jddddt|�g||d�|d	��qWd�n1sBwYnf|j����D]^\}}t�d
||d	�|rrz
t	�||d�Wn	tyqYnwz|d	��Wnty�}z|jtjtjfvr��WYd}~nd}~ww|d	��s�z|j|=WqOty�YqOwqOt��|j}t�d�|jr�t��|kr�|j����D]*\}}t�d
||d	�|d	�d�|d	��s�z|j|=Wq�ty�Yq�wq�|jr�t��|ks�d}|dk�rx|d8}|j����D]b\}}|d	���s.z|j|=Wn
t�y+Ynw�qt�d||d	�z
t	�|tj�W�qt�yr}z$t� |�|d	���sgz|j|=Wn
t�yfYnwWYd}~�qd}~ww|dk�s|j�r�|�!dd�}	|	dk�r�t�"dd�dd�|j��D���t�"d|	�|	d|d<|j#|i|��St�$dd�dd�|j��D���t�$d�dSdS)z*
        Kill all of the children
        rN�wbZtaskkillz/Fz/Tz/PIDr@r^zTerminating pid %s: %srz(Waiting to kill process manager childrenzJoining pid %s: %srrzKilling pid %s: %sZretryrxz4Some processes failed to respect the KILL signal: %sz; cs�$�|]
\}}d�|d|�VqdS�zProcess: {} (Pid: {})r^N�r���.0�k�vrrr�	<genexpr>�s
��
�z/ProcessManager.kill_children.<locals>.<genexpr>zkill_children retries left: %sz*Failed to kill the following processes: %scsr�r�r�r�rrrr��s��
�zLSalt will either fail to terminate now or leave some zombie processes behind)%r,r%r:rr6r�r
r&r'r�devnullr�r�rA�callr}r�r�rr�r�rrr�r�r�r�r�r�r�r�r��	exceptionr9rp�
kill_childrenr5)
r�r�r�r�r-Zp_mapr.Zend_timeZkill_iterationsZavailable_retriesrrrr��s�����������
���
�
���
�

��
��
��zProcessManager.kill_childrencCs |��|�tj�|��dS)zB
        Properly terminate this process manager instance
        N)r�r�r�r�r�r�rrrr�szProcessManager.terminatecOs�t�tjtj�t�tjtj�|��|�tj�t��|jkr:t	|j
�r+|j
|�S|j
dur8t�tj�|�SdS|j|i|��dSr�)
r�r��SIG_IGNr�r�r�rr[r��callabler��default_int_handlerr��r�r�r�rrrr�s


zProcessManager._handle_signals)Nr)NNN)F)r�r�r�r�r�r�r�r�r�r�	coroutiner�r�r�r�r�rrrrr��s

% (
ur�csHeZdZdZ�fdd�Zdd�Zdd�Zdd	�Zd
d�Zdd
�Z	�Z
S)r^a�

    Salt relies on this custom implementation of :py:class:`~multiprocessing.Process` to
    simplify/automate some common procedures, for example, logging in the new process is
    configured for "free" for every new process.
    This is most important in platforms which default to ``spawn` instead of ``fork`` for
    new processes.

    This is achieved by some dunder methods in the class:

    * ``__new__``:

        This method ensures that any arguments and/or keyword arguments that are passed to
        ``__init__`` are captured.

        By having this information captured, we can define ``__setstate__`` and ``__getstate__``
        to automatically take care of reconstructing the object state on spawned processes.

    * ``__getstate__``:

        This method should return a dictionary which will be used as the ``state`` argument to
        :py:method:`salt.utils.process.Process.__setstate__`.
        Usually, when subclassing, this method does not need to be implemented, however,
        if implemented, `super()` **must** be called.

    * ``__setstate__``:

        This method reconstructs the object on the spawned process.
        The ``state`` argument is constructed by the
        :py:method:`salt.utils.process.Process.__getstate__` method.
        Usually, when subclassing, this method does not need to be implemented, however,
        if implemented, `super()` **must** be called.


    An example of where ``__setstate__`` and ``__getstate__`` needed to be subclassed can be
    seen in :py:class:`salt.master.MWorker`.

    The gist of it is something like, if there are internal attributes which need to maintain
    their state on spawned processes, then, subclasses must implement ``__getstate__`` and
    ``__setstate__`` to ensure that.


    For example:


    .. code-block:: python

        import salt.utils.process

        class MyCustomProcess(salt.utils.process.Process):

            def __init__(self, opts, **kwargs):
                super().__init__(**kwargs)
                self.opts = opts

                # This attribute, counter, should only start at 0 on the initial(parent) process.
                # Any child processes, need to carry the current value of the counter(instead of
                # starting at zero).
                self.counter = 0

            def __getstate__(self):
                state = super().__getstate__()
                state.update(
                    {
                        "counter": self.counter,
                    }
                )
                return state

            def __setstate__(self, state):
                super().__setstate__(state)
                self.counter = state["counter"]
    cs`t��|�}g|_g|_tj��|_tjj	�
�r$t�|�|_t�|�|_
t|d|�|j��|S)au
        This method ensures that any arguments and/or keyword arguments that are passed to
        ``__init__`` are captured.

        By having this information captured, we can define ``__setstate__`` and ``__getstate__``
        to automatically take care of object pickling which is required for platforms that
        spawn processes instead of forking them.
        r�)�super�__new__�_after_fork_methods�_finalize_methodsr,�_logging�get_logging_options_dict�__logging_config__r%r:�spawning_platformr��_args_for_getstate�_kwargs_for_getstate�setattr�_Process__decorate_runr���clsr�r��instance�r�rrr�ps	zProcess.__new__cCs�|d}|d}|d}|j|i|��||_|dD]\}}}|j|g|�Ri|��q|dD]\}}}|j|g|�Ri|��q1dS)aD
        This method reconstructs the object on the spawned process.
        The ``state`` argument is constructed by :py:method:`salt.utils.process.Process.__getstate__`.

        Usually, when subclassing, this method does not need to be implemented, however,
        if implemented, `super()` **must** be called.
        r�r��logging_config�after_fork_methods�finalize_methodsN)r�r��register_after_fork_methodr�)r��stater�r�r	�functionrrr�__setstate__�s�zProcess.__setstate__cCs"|j}|j}|||j|j|jd�S)a5
        This method should return a dictionary which will be used as the ``state`` argument to
        :py:method:`salt.utils.process.Process.__setstate__`.
        Usually, when subclassing, this method does not need to be implemented, however,
        if implemented, `super()` **must** be called.
        )r�r�r
rr	)rrr�r�r�r�rrr�__getstate__�s�zProcess.__getstate__cst�����fdd��}|S)Ncs�t�j�tj��stj��j�tjj�	�s8ztj�
�Wnty7}z
t�
d�|�WYd}~nd}~wwztj��WntyX}z
t�
d�|�WYd}~nd}~ww�jD] \}}}z	||i|��Wq\ty|t�
d�|||�Yq\wz�zl��WWzF�jD] \}}}z	||i|��Wq�ty�t�
d�|||�Yq�wWztj�
�WSty�}z
t�
d�|�WYd}~Sd}~wwztj�
�Wwty�}z
t�
d�|�WYd}~wd}~wwty��t�ytjd�jdd��wzJ�jD]#\}}}z
||i|��W�qt�y+t�
d�|||�Y�qwWztj�
�Wwt�yN}z
t�
d�|�WYd}~wd}~wwztj�
�Wwt�yp}z
t�
d�|�WYd}~wd}~ww)	Nz2Failed to shutdown logging when starting on %s: %sz%Failed to configure logging on %s: %szJFailed to run after fork callback on %s; method=%r; args=%r; and kwargs=%r�HFailed to run finalize callback on %s; method=%r; args=%r; and kwargs=%rz$Failed to shutdown logging on %s: %szJAn un-handled exception from the multiprocessing process '%s' was caught:
Try)rr
r,r�r�Zset_logging_options_dictr�r%r:rZshutdown_loggingr�rr�Z
setup_loggingr�r��
SystemExitr)r.�methodr�r���run_funcr�rr�wrapped_run_func�s�

��������	����������	�
��������z0Process.__decorate_run.<locals>.wrapped_run_func)�	functools�wraps)r�rrrrrZ__decorate_run�sSzProcess.__decorate_runcO�(|||f}||jvr|j�|�dSdS)zI
        Register a function to run after the process has forked
        N)r�r�)r�rr�r�Zafter_fork_method_tuplerrrr�

�z"Process.register_after_fork_methodcOr)zB
        Register a function to run as process terminates
        N)r�r�)r�rr�r�Zfinalize_method_tuplerrrr�rz Process.register_finalize_method)r�r�r�r�r�rrrrr��
__classcell__rrrrr^&sI"Wr^cs8eZdZ�fdd�Zdd�Zdd�Z�fdd�Z�ZS)	r�cs,t�j|g|�Ri|��}|�tj|�|Sr�)r�r�rr��_setup_signalsrrrrr� s
�zSignalHandlingProcess.__new__cCs$t�tj|j�t�tj|j�dSr�)r�r�r�r�r�rrrr'sz$SignalHandlingProcess._setup_signalsc	CsZt�tjtj�t�tjtj�|jj�d�}|tjkr!|d7}n	|tjkr*|d7}|d7}t�|�|jD] \}}}z	||i|��Wq6t	yVt�
d||||�Yq6wtr�z5t�
t���}t|d�r�|jdd�D] }z
|��rw|��Wqltjy�t�d	|jt���YqlwWntjy�t�d
|jt���Ynwt�tjjj�dS)Nz received a r�r�z	. Exitingr�childrenT)�	recursivezCUnable to kill child of process %d, it does not exist. My pid is %dzEUnable to kill children of process %d, it does not exist.My pid is %d)r�r�r�r�r�r�rr~r�r�r�rfr\r^rr[�hasattrrZ
is_runningr�r_r5r-rr,rrr)	r��signumZsigframer�rr�r�rG�childrrrr�+s^



��

������z%SignalHandlingProcess._handle_signalscs>ttjtj��t���Wd�dS1swYdSr�)r�r�r�r�r�r�r�rrrr�^s"�zSignalHandlingProcess.start)r�r�r�r�rr�r�rrrrrr�s
3r�cgs��i}|D].}zt�|�}t�|tj�Wnty.}z
t�d||�WYd}~qd}~ww|||<qzdVW|D]
}t�|||�q;~dS|D]
}t�|||�qK~w)z>
    Temporarily restore signals to their default values.
    z+Failed to register signal for signum %d: %sN)r�r�r�r�rr�)ZsignalsZold_signalsr Zsaved_signalr.rrrr�cs&�
��
�r�c@s&eZdZddd�Zdd�Zdd�ZdS)	�SubprocessListNcCs:|durg|_n||_|durt��|_n||_d|_dSr�)�	processesr6�Lock�lock�count)r�r#r%rrrr��s
zSubprocessList.__init__cCsT|j�|j�|�t�d|j�|jd7_Wd�dS1s#wYdS)NzSubprocess %s addedr)r%r#r�rr~r
r&�r�r�rrr�add�s
"�zSubprocessList.addcCs�|j�A|jdd�D]0}|�d�t|d�r"|jdurq|��n|��r'q|j�|�|jd8_t	�
d|j�qWd�dS1sGwYdS)Ng{�G�z�?r�rzSubprocess %s cleaned up)r%r#r�rr�rUr��remover&rr~r
r'rrr�cleanup�s



�"�zSubprocessList.cleanupr�)r�r�r�r�r(r*rrrrr"�s
r"c
OsXtD]'\}}}t�d|||�z	||i|��Wqty)t�d|||�YqwdS)a�
    Generic process to allow for any registered process cleanup routines to execute.

    While class Process has a register_finalize_method, when a process is looked up by pid
    using psutil.Process, there is no method available to register a cleanup process.

    Hence, this function is added as part of the add_process to allow usage of other cleanup processes
    which cannot be added by the register_finalize_method.
    z7cleanup_finalize_process, method=%r, args=%r, kwargs=%rzVFailed to run registered function finalize callback; method=%r; args=%r; and kwargs=%rN)�(_INTERNAL_PROCESS_FINALIZE_FUNCTION_LISTrr~r�r�)r�r�rrrrr��s&����r�cOs4t�d|||�|||f}|tvrt�|�dSdS)a�
    Register a function to run as process terminates

    While class Process has a register_finalize_method, when a process is looked up by pid
    using psutil.Process, there is no method available to register a cleanup process.

    Hence, this function can be used to register a function to allow cleanup processes
    which cannot be added by class Process register_finalize_method.

    Note: there is no deletion, since it is assummed that if something is registered, it will continue to be used
    zIregister_cleanup_finalize_function entry, function=%r, args=%r, kwargs=%rN)rr~r+r�)rr�r�Zfinalize_function_tuplerrr�"register_cleanup_finalize_function�s�
�r,)Tr�)r�)>r��
contextlibr�rrr�r3rk�loggingr6Zmultiprocessing.utilrr�r�rPrAr r�r�Z
salt._loggingr,Zsalt.defaults.exitcodesZsalt.utils.filesZsalt.utils.pathZsalt.utils.platformZsalt.utils.versionsZsalt.ext.tornadorrZ_get_machine_identifier�	getLoggerr�rrfr\rLrrr+rr/r(r=rIrZr`rvrwr�r�r�r�r�r�r�r^r��contextmanagerr�r"r�r,rrrr�<module>s�
��
/
 5"1
H?zD
$