14adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao# 24adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao# Module providing the `Process` class which emulates `threading.Thread` 34adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao# 44adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao# multiprocessing/process.py 54adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao# 64adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao# Copyright (c) 2006-2008, R Oudkerk 74adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao# All rights reserved. 84adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao# 94adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao# Redistribution and use in source and binary forms, with or without 104adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao# modification, are permitted provided that the following conditions 114adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao# are met: 124adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao# 134adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao# 1. Redistributions of source code must retain the above copyright 144adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao# notice, this list of conditions and the following disclaimer. 154adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao# 2. Redistributions in binary form must reproduce the above copyright 164adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao# notice, this list of conditions and the following disclaimer in the 174adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao# documentation and/or other materials provided with the distribution. 184adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao# 3. Neither the name of author nor the names of any contributors may be 194adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao# used to endorse or promote products derived from this software 204adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao# without specific prior written permission. 214adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao# 224adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS "AS IS" AND 234adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 244adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 254adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 264adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 274adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 284adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 294adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 304adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 314adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 324adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao# SUCH DAMAGE. 334adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao# 344adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 354adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao__all__ = ['Process', 'current_process', 'active_children'] 364adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 374adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao# 384adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao# Imports 394adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao# 404adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 414adfde8bc82dd39f59e0445588c3e599ada477dJosh Gaoimport os 424adfde8bc82dd39f59e0445588c3e599ada477dJosh Gaoimport sys 434adfde8bc82dd39f59e0445588c3e599ada477dJosh Gaoimport signal 444adfde8bc82dd39f59e0445588c3e599ada477dJosh Gaoimport itertools 454adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 464adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao# 474adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao# 484adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao# 494adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 504adfde8bc82dd39f59e0445588c3e599ada477dJosh Gaotry: 514adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao ORIGINAL_DIR = os.path.abspath(os.getcwd()) 524adfde8bc82dd39f59e0445588c3e599ada477dJosh Gaoexcept OSError: 534adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao ORIGINAL_DIR = None 544adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 554adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao# 564adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao# Public functions 574adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao# 584adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 594adfde8bc82dd39f59e0445588c3e599ada477dJosh Gaodef current_process(): 604adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao ''' 614adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao Return process object representing the current process 624adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao ''' 634adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao return _current_process 644adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 654adfde8bc82dd39f59e0445588c3e599ada477dJosh Gaodef active_children(): 664adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao ''' 674adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao Return list of process objects corresponding to live child processes 684adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao ''' 694adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao _cleanup() 704adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao return list(_current_process._children) 714adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 724adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao# 734adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao# 744adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao# 754adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 764adfde8bc82dd39f59e0445588c3e599ada477dJosh Gaodef _cleanup(): 774adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao # check for processes which have finished 784adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao for p in list(_current_process._children): 794adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao if p._popen.poll() is not None: 804adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao _current_process._children.discard(p) 814adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 824adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao# 834adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao# The `Process` class 844adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao# 854adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 864adfde8bc82dd39f59e0445588c3e599ada477dJosh Gaoclass Process(object): 874adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao ''' 884adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao Process objects represent activity that is run in a separate process 894adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 904adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao The class is analagous to `threading.Thread` 914adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao ''' 924adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao _Popen = None 934adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 944adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def __init__(self, group=None, target=None, name=None, args=(), kwargs={}): 954adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao assert group is None, 'group argument must be None for now' 964adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao count = _current_process._counter.next() 974adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self._identity = _current_process._identity + (count,) 984adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self._authkey = _current_process._authkey 994adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self._daemonic = _current_process._daemonic 1004adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self._tempdir = _current_process._tempdir 1014adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self._parent_pid = os.getpid() 1024adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self._popen = None 1034adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self._target = target 1044adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self._args = tuple(args) 1054adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self._kwargs = dict(kwargs) 1064adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self._name = name or type(self).__name__ + '-' + \ 1074adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao ':'.join(str(i) for i in self._identity) 1084adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 1094adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def run(self): 1104adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao ''' 1114adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao Method to be run in sub-process; can be overridden in sub-class 1124adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao ''' 1134adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao if self._target: 1144adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self._target(*self._args, **self._kwargs) 1154adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 1164adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def start(self): 1174adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao ''' 1184adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao Start child process 1194adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao ''' 1204adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao assert self._popen is None, 'cannot start a process twice' 1214adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao assert self._parent_pid == os.getpid(), \ 1224adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 'can only start a process object created by current process' 1234adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao assert not _current_process._daemonic, \ 1244adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 'daemonic processes are not allowed to have children' 1254adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao _cleanup() 1264adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao if self._Popen is not None: 1274adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao Popen = self._Popen 1284adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao else: 1294adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao from .forking import Popen 1304adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self._popen = Popen(self) 1314adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao _current_process._children.add(self) 1324adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 1334adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def terminate(self): 1344adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao ''' 1354adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao Terminate process; sends SIGTERM signal or uses TerminateProcess() 1364adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao ''' 1374adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self._popen.terminate() 1384adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 1394adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def join(self, timeout=None): 1404adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao ''' 1414adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao Wait until child process terminates 1424adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao ''' 1434adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao assert self._parent_pid == os.getpid(), 'can only join a child process' 1444adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao assert self._popen is not None, 'can only join a started process' 1454adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao res = self._popen.wait(timeout) 1464adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao if res is not None: 1474adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao _current_process._children.discard(self) 1484adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 1494adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def is_alive(self): 1504adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao ''' 1514adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao Return whether process is alive 1524adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao ''' 1534adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao if self is _current_process: 1544adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao return True 1554adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao assert self._parent_pid == os.getpid(), 'can only test a child process' 1564adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao if self._popen is None: 1574adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao return False 1584adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self._popen.poll() 1594adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao return self._popen.returncode is None 1604adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 1614adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao @property 1624adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def name(self): 1634adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao return self._name 1644adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 1654adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao @name.setter 1664adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def name(self, name): 1674adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao assert isinstance(name, basestring), 'name must be a string' 1684adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self._name = name 1694adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 1704adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao @property 1714adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def daemon(self): 1724adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao ''' 1734adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao Return whether process is a daemon 1744adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao ''' 1754adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao return self._daemonic 1764adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 1774adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao @daemon.setter 1784adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def daemon(self, daemonic): 1794adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao ''' 1804adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao Set whether process is a daemon 1814adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao ''' 1824adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao assert self._popen is None, 'process has already started' 1834adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self._daemonic = daemonic 1844adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 1854adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao @property 1864adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def authkey(self): 1874adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao return self._authkey 1884adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 1894adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao @authkey.setter 1904adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def authkey(self, authkey): 1914adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao ''' 1924adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao Set authorization key of process 1934adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao ''' 1944adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self._authkey = AuthenticationString(authkey) 1954adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 1964adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao @property 1974adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def exitcode(self): 1984adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao ''' 1994adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao Return exit code of process or `None` if it has yet to stop 2004adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao ''' 2014adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao if self._popen is None: 2024adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao return self._popen 2034adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao return self._popen.poll() 2044adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 2054adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao @property 2064adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def ident(self): 2074adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao ''' 2084adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao Return identifier (PID) of process or `None` if it has yet to start 2094adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao ''' 2104adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao if self is _current_process: 2114adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao return os.getpid() 2124adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao else: 2134adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao return self._popen and self._popen.pid 2144adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 2154adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao pid = ident 2164adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 2174adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def __repr__(self): 2184adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao if self is _current_process: 2194adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao status = 'started' 2204adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao elif self._parent_pid != os.getpid(): 2214adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao status = 'unknown' 2224adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao elif self._popen is None: 2234adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao status = 'initial' 2244adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao else: 2254adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao if self._popen.poll() is not None: 2264adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao status = self.exitcode 2274adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao else: 2284adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao status = 'started' 2294adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 2304adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao if type(status) is int: 2314adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao if status == 0: 2324adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao status = 'stopped' 2334adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao else: 2344adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao status = 'stopped[%s]' % _exitcode_to_name.get(status, status) 2354adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 2364adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao return '<%s(%s, %s%s)>' % (type(self).__name__, self._name, 2374adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao status, self._daemonic and ' daemon' or '') 2384adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 2394adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao ## 2404adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 2414adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def _bootstrap(self): 2424adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao from . import util 2434adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao global _current_process 2444adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 2454adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao try: 2464adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self._children = set() 2474adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self._counter = itertools.count(1) 2484adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao try: 2494adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao sys.stdin.close() 2504adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao sys.stdin = open(os.devnull) 2514adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao except (OSError, ValueError): 2524adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao pass 2534adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao _current_process = self 2544adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao util._finalizer_registry.clear() 2554adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao util._run_after_forkers() 2564adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao util.info('child process calling self.run()') 2574adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao try: 2584adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.run() 2594adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao exitcode = 0 2604adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao finally: 2614adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao util._exit_function() 2624adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao except SystemExit, e: 2634adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao if not e.args: 2644adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao exitcode = 1 2654adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao elif isinstance(e.args[0], int): 2664adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao exitcode = e.args[0] 2674adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao else: 2684adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao sys.stderr.write(str(e.args[0]) + '\n') 2694adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao sys.stderr.flush() 2704adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao exitcode = 0 if isinstance(e.args[0], str) else 1 2714adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao except: 2724adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao exitcode = 1 2734adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao import traceback 2744adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao sys.stderr.write('Process %s:\n' % self.name) 2754adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao sys.stderr.flush() 2764adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao traceback.print_exc() 2774adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 2784adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao util.info('process exiting with exitcode %d' % exitcode) 2794adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao return exitcode 2804adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 2814adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao# 2824adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao# We subclass bytes to avoid accidental transmission of auth keys over network 2834adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao# 2844adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 2854adfde8bc82dd39f59e0445588c3e599ada477dJosh Gaoclass AuthenticationString(bytes): 2864adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def __reduce__(self): 2874adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao from .forking import Popen 2884adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao if not Popen.thread_is_spawning(): 2894adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao raise TypeError( 2904adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 'Pickling an AuthenticationString object is ' 2914adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 'disallowed for security reasons' 2924adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao ) 2934adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao return AuthenticationString, (bytes(self),) 2944adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 2954adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao# 2964adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao# Create object representing the main process 2974adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao# 2984adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 2994adfde8bc82dd39f59e0445588c3e599ada477dJosh Gaoclass _MainProcess(Process): 3004adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 3014adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def __init__(self): 3024adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self._identity = () 3034adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self._daemonic = False 3044adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self._name = 'MainProcess' 3054adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self._parent_pid = None 3064adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self._popen = None 3074adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self._counter = itertools.count(1) 3084adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self._children = set() 3094adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self._authkey = AuthenticationString(os.urandom(32)) 3104adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self._tempdir = None 3114adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 3124adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao_current_process = _MainProcess() 3134adfde8bc82dd39f59e0445588c3e599ada477dJosh Gaodel _MainProcess 3144adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 3154adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao# 3164adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao# Give names to some return codes 3174adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao# 3184adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 3194adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao_exitcode_to_name = {} 3204adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 3214adfde8bc82dd39f59e0445588c3e599ada477dJosh Gaofor name, signum in signal.__dict__.items(): 3224adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao if name[:3]=='SIG' and '_' not in name: 3234adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao _exitcode_to_name[-signum] = name 324