10a8c90248264a8b26970b4473770bcc3df8515fJosh Gao# 20a8c90248264a8b26970b4473770bcc3df8515fJosh Gao# Module providing the `Process` class which emulates `threading.Thread` 30a8c90248264a8b26970b4473770bcc3df8515fJosh Gao# 40a8c90248264a8b26970b4473770bcc3df8515fJosh Gao# multiprocessing/process.py 50a8c90248264a8b26970b4473770bcc3df8515fJosh Gao# 60a8c90248264a8b26970b4473770bcc3df8515fJosh Gao# Copyright (c) 2006-2008, R Oudkerk 70a8c90248264a8b26970b4473770bcc3df8515fJosh Gao# All rights reserved. 80a8c90248264a8b26970b4473770bcc3df8515fJosh Gao# 90a8c90248264a8b26970b4473770bcc3df8515fJosh Gao# Redistribution and use in source and binary forms, with or without 100a8c90248264a8b26970b4473770bcc3df8515fJosh Gao# modification, are permitted provided that the following conditions 110a8c90248264a8b26970b4473770bcc3df8515fJosh Gao# are met: 120a8c90248264a8b26970b4473770bcc3df8515fJosh Gao# 130a8c90248264a8b26970b4473770bcc3df8515fJosh Gao# 1. Redistributions of source code must retain the above copyright 140a8c90248264a8b26970b4473770bcc3df8515fJosh Gao# notice, this list of conditions and the following disclaimer. 150a8c90248264a8b26970b4473770bcc3df8515fJosh Gao# 2. Redistributions in binary form must reproduce the above copyright 160a8c90248264a8b26970b4473770bcc3df8515fJosh Gao# notice, this list of conditions and the following disclaimer in the 170a8c90248264a8b26970b4473770bcc3df8515fJosh Gao# documentation and/or other materials provided with the distribution. 180a8c90248264a8b26970b4473770bcc3df8515fJosh Gao# 3. Neither the name of author nor the names of any contributors may be 190a8c90248264a8b26970b4473770bcc3df8515fJosh Gao# used to endorse or promote products derived from this software 200a8c90248264a8b26970b4473770bcc3df8515fJosh Gao# without specific prior written permission. 210a8c90248264a8b26970b4473770bcc3df8515fJosh Gao# 220a8c90248264a8b26970b4473770bcc3df8515fJosh Gao# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS "AS IS" AND 230a8c90248264a8b26970b4473770bcc3df8515fJosh Gao# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 240a8c90248264a8b26970b4473770bcc3df8515fJosh Gao# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 250a8c90248264a8b26970b4473770bcc3df8515fJosh Gao# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 260a8c90248264a8b26970b4473770bcc3df8515fJosh Gao# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 270a8c90248264a8b26970b4473770bcc3df8515fJosh Gao# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 280a8c90248264a8b26970b4473770bcc3df8515fJosh Gao# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 290a8c90248264a8b26970b4473770bcc3df8515fJosh Gao# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 300a8c90248264a8b26970b4473770bcc3df8515fJosh Gao# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 310a8c90248264a8b26970b4473770bcc3df8515fJosh Gao# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 320a8c90248264a8b26970b4473770bcc3df8515fJosh Gao# SUCH DAMAGE. 330a8c90248264a8b26970b4473770bcc3df8515fJosh Gao# 340a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 350a8c90248264a8b26970b4473770bcc3df8515fJosh Gao__all__ = ['Process', 'current_process', 'active_children'] 360a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 370a8c90248264a8b26970b4473770bcc3df8515fJosh Gao# 380a8c90248264a8b26970b4473770bcc3df8515fJosh Gao# Imports 390a8c90248264a8b26970b4473770bcc3df8515fJosh Gao# 400a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 410a8c90248264a8b26970b4473770bcc3df8515fJosh Gaoimport os 420a8c90248264a8b26970b4473770bcc3df8515fJosh Gaoimport sys 430a8c90248264a8b26970b4473770bcc3df8515fJosh Gaoimport signal 440a8c90248264a8b26970b4473770bcc3df8515fJosh Gaoimport itertools 450a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 460a8c90248264a8b26970b4473770bcc3df8515fJosh Gao# 470a8c90248264a8b26970b4473770bcc3df8515fJosh Gao# 480a8c90248264a8b26970b4473770bcc3df8515fJosh Gao# 490a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 500a8c90248264a8b26970b4473770bcc3df8515fJosh Gaotry: 510a8c90248264a8b26970b4473770bcc3df8515fJosh Gao ORIGINAL_DIR = os.path.abspath(os.getcwd()) 520a8c90248264a8b26970b4473770bcc3df8515fJosh Gaoexcept OSError: 530a8c90248264a8b26970b4473770bcc3df8515fJosh Gao ORIGINAL_DIR = None 540a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 550a8c90248264a8b26970b4473770bcc3df8515fJosh Gao# 560a8c90248264a8b26970b4473770bcc3df8515fJosh Gao# Public functions 570a8c90248264a8b26970b4473770bcc3df8515fJosh Gao# 580a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 590a8c90248264a8b26970b4473770bcc3df8515fJosh Gaodef current_process(): 600a8c90248264a8b26970b4473770bcc3df8515fJosh Gao ''' 610a8c90248264a8b26970b4473770bcc3df8515fJosh Gao Return process object representing the current process 620a8c90248264a8b26970b4473770bcc3df8515fJosh Gao ''' 630a8c90248264a8b26970b4473770bcc3df8515fJosh Gao return _current_process 640a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 650a8c90248264a8b26970b4473770bcc3df8515fJosh Gaodef active_children(): 660a8c90248264a8b26970b4473770bcc3df8515fJosh Gao ''' 670a8c90248264a8b26970b4473770bcc3df8515fJosh Gao Return list of process objects corresponding to live child processes 680a8c90248264a8b26970b4473770bcc3df8515fJosh Gao ''' 690a8c90248264a8b26970b4473770bcc3df8515fJosh Gao _cleanup() 700a8c90248264a8b26970b4473770bcc3df8515fJosh Gao return list(_current_process._children) 710a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 720a8c90248264a8b26970b4473770bcc3df8515fJosh Gao# 730a8c90248264a8b26970b4473770bcc3df8515fJosh Gao# 740a8c90248264a8b26970b4473770bcc3df8515fJosh Gao# 750a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 760a8c90248264a8b26970b4473770bcc3df8515fJosh Gaodef _cleanup(): 770a8c90248264a8b26970b4473770bcc3df8515fJosh Gao # check for processes which have finished 780a8c90248264a8b26970b4473770bcc3df8515fJosh Gao for p in list(_current_process._children): 790a8c90248264a8b26970b4473770bcc3df8515fJosh Gao if p._popen.poll() is not None: 800a8c90248264a8b26970b4473770bcc3df8515fJosh Gao _current_process._children.discard(p) 810a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 820a8c90248264a8b26970b4473770bcc3df8515fJosh Gao# 830a8c90248264a8b26970b4473770bcc3df8515fJosh Gao# The `Process` class 840a8c90248264a8b26970b4473770bcc3df8515fJosh Gao# 850a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 860a8c90248264a8b26970b4473770bcc3df8515fJosh Gaoclass Process(object): 870a8c90248264a8b26970b4473770bcc3df8515fJosh Gao ''' 880a8c90248264a8b26970b4473770bcc3df8515fJosh Gao Process objects represent activity that is run in a separate process 890a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 900a8c90248264a8b26970b4473770bcc3df8515fJosh Gao The class is analagous to `threading.Thread` 910a8c90248264a8b26970b4473770bcc3df8515fJosh Gao ''' 920a8c90248264a8b26970b4473770bcc3df8515fJosh Gao _Popen = None 930a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 940a8c90248264a8b26970b4473770bcc3df8515fJosh Gao def __init__(self, group=None, target=None, name=None, args=(), kwargs={}): 950a8c90248264a8b26970b4473770bcc3df8515fJosh Gao assert group is None, 'group argument must be None for now' 960a8c90248264a8b26970b4473770bcc3df8515fJosh Gao count = _current_process._counter.next() 970a8c90248264a8b26970b4473770bcc3df8515fJosh Gao self._identity = _current_process._identity + (count,) 980a8c90248264a8b26970b4473770bcc3df8515fJosh Gao self._authkey = _current_process._authkey 990a8c90248264a8b26970b4473770bcc3df8515fJosh Gao self._daemonic = _current_process._daemonic 1000a8c90248264a8b26970b4473770bcc3df8515fJosh Gao self._tempdir = _current_process._tempdir 1010a8c90248264a8b26970b4473770bcc3df8515fJosh Gao self._parent_pid = os.getpid() 1020a8c90248264a8b26970b4473770bcc3df8515fJosh Gao self._popen = None 1030a8c90248264a8b26970b4473770bcc3df8515fJosh Gao self._target = target 1040a8c90248264a8b26970b4473770bcc3df8515fJosh Gao self._args = tuple(args) 1050a8c90248264a8b26970b4473770bcc3df8515fJosh Gao self._kwargs = dict(kwargs) 1060a8c90248264a8b26970b4473770bcc3df8515fJosh Gao self._name = name or type(self).__name__ + '-' + \ 1070a8c90248264a8b26970b4473770bcc3df8515fJosh Gao ':'.join(str(i) for i in self._identity) 1080a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 1090a8c90248264a8b26970b4473770bcc3df8515fJosh Gao def run(self): 1100a8c90248264a8b26970b4473770bcc3df8515fJosh Gao ''' 1110a8c90248264a8b26970b4473770bcc3df8515fJosh Gao Method to be run in sub-process; can be overridden in sub-class 1120a8c90248264a8b26970b4473770bcc3df8515fJosh Gao ''' 1130a8c90248264a8b26970b4473770bcc3df8515fJosh Gao if self._target: 1140a8c90248264a8b26970b4473770bcc3df8515fJosh Gao self._target(*self._args, **self._kwargs) 1150a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 1160a8c90248264a8b26970b4473770bcc3df8515fJosh Gao def start(self): 1170a8c90248264a8b26970b4473770bcc3df8515fJosh Gao ''' 1180a8c90248264a8b26970b4473770bcc3df8515fJosh Gao Start child process 1190a8c90248264a8b26970b4473770bcc3df8515fJosh Gao ''' 1200a8c90248264a8b26970b4473770bcc3df8515fJosh Gao assert self._popen is None, 'cannot start a process twice' 1210a8c90248264a8b26970b4473770bcc3df8515fJosh Gao assert self._parent_pid == os.getpid(), \ 1220a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 'can only start a process object created by current process' 1230a8c90248264a8b26970b4473770bcc3df8515fJosh Gao assert not _current_process._daemonic, \ 1240a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 'daemonic processes are not allowed to have children' 1250a8c90248264a8b26970b4473770bcc3df8515fJosh Gao _cleanup() 1260a8c90248264a8b26970b4473770bcc3df8515fJosh Gao if self._Popen is not None: 1270a8c90248264a8b26970b4473770bcc3df8515fJosh Gao Popen = self._Popen 1280a8c90248264a8b26970b4473770bcc3df8515fJosh Gao else: 1290a8c90248264a8b26970b4473770bcc3df8515fJosh Gao from .forking import Popen 1300a8c90248264a8b26970b4473770bcc3df8515fJosh Gao self._popen = Popen(self) 1310a8c90248264a8b26970b4473770bcc3df8515fJosh Gao _current_process._children.add(self) 1320a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 1330a8c90248264a8b26970b4473770bcc3df8515fJosh Gao def terminate(self): 1340a8c90248264a8b26970b4473770bcc3df8515fJosh Gao ''' 1350a8c90248264a8b26970b4473770bcc3df8515fJosh Gao Terminate process; sends SIGTERM signal or uses TerminateProcess() 1360a8c90248264a8b26970b4473770bcc3df8515fJosh Gao ''' 1370a8c90248264a8b26970b4473770bcc3df8515fJosh Gao self._popen.terminate() 1380a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 1390a8c90248264a8b26970b4473770bcc3df8515fJosh Gao def join(self, timeout=None): 1400a8c90248264a8b26970b4473770bcc3df8515fJosh Gao ''' 1410a8c90248264a8b26970b4473770bcc3df8515fJosh Gao Wait until child process terminates 1420a8c90248264a8b26970b4473770bcc3df8515fJosh Gao ''' 1430a8c90248264a8b26970b4473770bcc3df8515fJosh Gao assert self._parent_pid == os.getpid(), 'can only join a child process' 1440a8c90248264a8b26970b4473770bcc3df8515fJosh Gao assert self._popen is not None, 'can only join a started process' 1450a8c90248264a8b26970b4473770bcc3df8515fJosh Gao res = self._popen.wait(timeout) 1460a8c90248264a8b26970b4473770bcc3df8515fJosh Gao if res is not None: 1470a8c90248264a8b26970b4473770bcc3df8515fJosh Gao _current_process._children.discard(self) 1480a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 1490a8c90248264a8b26970b4473770bcc3df8515fJosh Gao def is_alive(self): 1500a8c90248264a8b26970b4473770bcc3df8515fJosh Gao ''' 1510a8c90248264a8b26970b4473770bcc3df8515fJosh Gao Return whether process is alive 1520a8c90248264a8b26970b4473770bcc3df8515fJosh Gao ''' 1530a8c90248264a8b26970b4473770bcc3df8515fJosh Gao if self is _current_process: 1540a8c90248264a8b26970b4473770bcc3df8515fJosh Gao return True 1550a8c90248264a8b26970b4473770bcc3df8515fJosh Gao assert self._parent_pid == os.getpid(), 'can only test a child process' 1560a8c90248264a8b26970b4473770bcc3df8515fJosh Gao if self._popen is None: 1570a8c90248264a8b26970b4473770bcc3df8515fJosh Gao return False 1580a8c90248264a8b26970b4473770bcc3df8515fJosh Gao self._popen.poll() 1590a8c90248264a8b26970b4473770bcc3df8515fJosh Gao return self._popen.returncode is None 1600a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 1610a8c90248264a8b26970b4473770bcc3df8515fJosh Gao @property 1620a8c90248264a8b26970b4473770bcc3df8515fJosh Gao def name(self): 1630a8c90248264a8b26970b4473770bcc3df8515fJosh Gao return self._name 1640a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 1650a8c90248264a8b26970b4473770bcc3df8515fJosh Gao @name.setter 1660a8c90248264a8b26970b4473770bcc3df8515fJosh Gao def name(self, name): 1670a8c90248264a8b26970b4473770bcc3df8515fJosh Gao assert isinstance(name, basestring), 'name must be a string' 1680a8c90248264a8b26970b4473770bcc3df8515fJosh Gao self._name = name 1690a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 1700a8c90248264a8b26970b4473770bcc3df8515fJosh Gao @property 1710a8c90248264a8b26970b4473770bcc3df8515fJosh Gao def daemon(self): 1720a8c90248264a8b26970b4473770bcc3df8515fJosh Gao ''' 1730a8c90248264a8b26970b4473770bcc3df8515fJosh Gao Return whether process is a daemon 1740a8c90248264a8b26970b4473770bcc3df8515fJosh Gao ''' 1750a8c90248264a8b26970b4473770bcc3df8515fJosh Gao return self._daemonic 1760a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 1770a8c90248264a8b26970b4473770bcc3df8515fJosh Gao @daemon.setter 1780a8c90248264a8b26970b4473770bcc3df8515fJosh Gao def daemon(self, daemonic): 1790a8c90248264a8b26970b4473770bcc3df8515fJosh Gao ''' 1800a8c90248264a8b26970b4473770bcc3df8515fJosh Gao Set whether process is a daemon 1810a8c90248264a8b26970b4473770bcc3df8515fJosh Gao ''' 1820a8c90248264a8b26970b4473770bcc3df8515fJosh Gao assert self._popen is None, 'process has already started' 1830a8c90248264a8b26970b4473770bcc3df8515fJosh Gao self._daemonic = daemonic 1840a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 1850a8c90248264a8b26970b4473770bcc3df8515fJosh Gao @property 1860a8c90248264a8b26970b4473770bcc3df8515fJosh Gao def authkey(self): 1870a8c90248264a8b26970b4473770bcc3df8515fJosh Gao return self._authkey 1880a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 1890a8c90248264a8b26970b4473770bcc3df8515fJosh Gao @authkey.setter 1900a8c90248264a8b26970b4473770bcc3df8515fJosh Gao def authkey(self, authkey): 1910a8c90248264a8b26970b4473770bcc3df8515fJosh Gao ''' 1920a8c90248264a8b26970b4473770bcc3df8515fJosh Gao Set authorization key of process 1930a8c90248264a8b26970b4473770bcc3df8515fJosh Gao ''' 1940a8c90248264a8b26970b4473770bcc3df8515fJosh Gao self._authkey = AuthenticationString(authkey) 1950a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 1960a8c90248264a8b26970b4473770bcc3df8515fJosh Gao @property 1970a8c90248264a8b26970b4473770bcc3df8515fJosh Gao def exitcode(self): 1980a8c90248264a8b26970b4473770bcc3df8515fJosh Gao ''' 1990a8c90248264a8b26970b4473770bcc3df8515fJosh Gao Return exit code of process or `None` if it has yet to stop 2000a8c90248264a8b26970b4473770bcc3df8515fJosh Gao ''' 2010a8c90248264a8b26970b4473770bcc3df8515fJosh Gao if self._popen is None: 2020a8c90248264a8b26970b4473770bcc3df8515fJosh Gao return self._popen 2030a8c90248264a8b26970b4473770bcc3df8515fJosh Gao return self._popen.poll() 2040a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 2050a8c90248264a8b26970b4473770bcc3df8515fJosh Gao @property 2060a8c90248264a8b26970b4473770bcc3df8515fJosh Gao def ident(self): 2070a8c90248264a8b26970b4473770bcc3df8515fJosh Gao ''' 2080a8c90248264a8b26970b4473770bcc3df8515fJosh Gao Return identifier (PID) of process or `None` if it has yet to start 2090a8c90248264a8b26970b4473770bcc3df8515fJosh Gao ''' 2100a8c90248264a8b26970b4473770bcc3df8515fJosh Gao if self is _current_process: 2110a8c90248264a8b26970b4473770bcc3df8515fJosh Gao return os.getpid() 2120a8c90248264a8b26970b4473770bcc3df8515fJosh Gao else: 2130a8c90248264a8b26970b4473770bcc3df8515fJosh Gao return self._popen and self._popen.pid 2140a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 2150a8c90248264a8b26970b4473770bcc3df8515fJosh Gao pid = ident 2160a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 2170a8c90248264a8b26970b4473770bcc3df8515fJosh Gao def __repr__(self): 2180a8c90248264a8b26970b4473770bcc3df8515fJosh Gao if self is _current_process: 2190a8c90248264a8b26970b4473770bcc3df8515fJosh Gao status = 'started' 2200a8c90248264a8b26970b4473770bcc3df8515fJosh Gao elif self._parent_pid != os.getpid(): 2210a8c90248264a8b26970b4473770bcc3df8515fJosh Gao status = 'unknown' 2220a8c90248264a8b26970b4473770bcc3df8515fJosh Gao elif self._popen is None: 2230a8c90248264a8b26970b4473770bcc3df8515fJosh Gao status = 'initial' 2240a8c90248264a8b26970b4473770bcc3df8515fJosh Gao else: 2250a8c90248264a8b26970b4473770bcc3df8515fJosh Gao if self._popen.poll() is not None: 2260a8c90248264a8b26970b4473770bcc3df8515fJosh Gao status = self.exitcode 2270a8c90248264a8b26970b4473770bcc3df8515fJosh Gao else: 2280a8c90248264a8b26970b4473770bcc3df8515fJosh Gao status = 'started' 2290a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 2300a8c90248264a8b26970b4473770bcc3df8515fJosh Gao if type(status) is int: 2310a8c90248264a8b26970b4473770bcc3df8515fJosh Gao if status == 0: 2320a8c90248264a8b26970b4473770bcc3df8515fJosh Gao status = 'stopped' 2330a8c90248264a8b26970b4473770bcc3df8515fJosh Gao else: 2340a8c90248264a8b26970b4473770bcc3df8515fJosh Gao status = 'stopped[%s]' % _exitcode_to_name.get(status, status) 2350a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 2360a8c90248264a8b26970b4473770bcc3df8515fJosh Gao return '<%s(%s, %s%s)>' % (type(self).__name__, self._name, 2370a8c90248264a8b26970b4473770bcc3df8515fJosh Gao status, self._daemonic and ' daemon' or '') 2380a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 2390a8c90248264a8b26970b4473770bcc3df8515fJosh Gao ## 2400a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 2410a8c90248264a8b26970b4473770bcc3df8515fJosh Gao def _bootstrap(self): 2420a8c90248264a8b26970b4473770bcc3df8515fJosh Gao from . import util 2430a8c90248264a8b26970b4473770bcc3df8515fJosh Gao global _current_process 2440a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 2450a8c90248264a8b26970b4473770bcc3df8515fJosh Gao try: 2460a8c90248264a8b26970b4473770bcc3df8515fJosh Gao self._children = set() 2470a8c90248264a8b26970b4473770bcc3df8515fJosh Gao self._counter = itertools.count(1) 2480a8c90248264a8b26970b4473770bcc3df8515fJosh Gao try: 2490a8c90248264a8b26970b4473770bcc3df8515fJosh Gao sys.stdin.close() 2500a8c90248264a8b26970b4473770bcc3df8515fJosh Gao sys.stdin = open(os.devnull) 2510a8c90248264a8b26970b4473770bcc3df8515fJosh Gao except (OSError, ValueError): 2520a8c90248264a8b26970b4473770bcc3df8515fJosh Gao pass 2530a8c90248264a8b26970b4473770bcc3df8515fJosh Gao _current_process = self 2540a8c90248264a8b26970b4473770bcc3df8515fJosh Gao util._finalizer_registry.clear() 2550a8c90248264a8b26970b4473770bcc3df8515fJosh Gao util._run_after_forkers() 2560a8c90248264a8b26970b4473770bcc3df8515fJosh Gao util.info('child process calling self.run()') 2570a8c90248264a8b26970b4473770bcc3df8515fJosh Gao try: 2580a8c90248264a8b26970b4473770bcc3df8515fJosh Gao self.run() 2590a8c90248264a8b26970b4473770bcc3df8515fJosh Gao exitcode = 0 2600a8c90248264a8b26970b4473770bcc3df8515fJosh Gao finally: 2610a8c90248264a8b26970b4473770bcc3df8515fJosh Gao util._exit_function() 2620a8c90248264a8b26970b4473770bcc3df8515fJosh Gao except SystemExit, e: 2630a8c90248264a8b26970b4473770bcc3df8515fJosh Gao if not e.args: 2640a8c90248264a8b26970b4473770bcc3df8515fJosh Gao exitcode = 1 2650a8c90248264a8b26970b4473770bcc3df8515fJosh Gao elif isinstance(e.args[0], int): 2660a8c90248264a8b26970b4473770bcc3df8515fJosh Gao exitcode = e.args[0] 2670a8c90248264a8b26970b4473770bcc3df8515fJosh Gao else: 2680a8c90248264a8b26970b4473770bcc3df8515fJosh Gao sys.stderr.write(str(e.args[0]) + '\n') 2690a8c90248264a8b26970b4473770bcc3df8515fJosh Gao sys.stderr.flush() 2700a8c90248264a8b26970b4473770bcc3df8515fJosh Gao exitcode = 0 if isinstance(e.args[0], str) else 1 2710a8c90248264a8b26970b4473770bcc3df8515fJosh Gao except: 2720a8c90248264a8b26970b4473770bcc3df8515fJosh Gao exitcode = 1 2730a8c90248264a8b26970b4473770bcc3df8515fJosh Gao import traceback 2740a8c90248264a8b26970b4473770bcc3df8515fJosh Gao sys.stderr.write('Process %s:\n' % self.name) 2750a8c90248264a8b26970b4473770bcc3df8515fJosh Gao sys.stderr.flush() 2760a8c90248264a8b26970b4473770bcc3df8515fJosh Gao traceback.print_exc() 2770a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 2780a8c90248264a8b26970b4473770bcc3df8515fJosh Gao util.info('process exiting with exitcode %d' % exitcode) 2790a8c90248264a8b26970b4473770bcc3df8515fJosh Gao return exitcode 2800a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 2810a8c90248264a8b26970b4473770bcc3df8515fJosh Gao# 2820a8c90248264a8b26970b4473770bcc3df8515fJosh Gao# We subclass bytes to avoid accidental transmission of auth keys over network 2830a8c90248264a8b26970b4473770bcc3df8515fJosh Gao# 2840a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 2850a8c90248264a8b26970b4473770bcc3df8515fJosh Gaoclass AuthenticationString(bytes): 2860a8c90248264a8b26970b4473770bcc3df8515fJosh Gao def __reduce__(self): 2870a8c90248264a8b26970b4473770bcc3df8515fJosh Gao from .forking import Popen 2880a8c90248264a8b26970b4473770bcc3df8515fJosh Gao if not Popen.thread_is_spawning(): 2890a8c90248264a8b26970b4473770bcc3df8515fJosh Gao raise TypeError( 2900a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 'Pickling an AuthenticationString object is ' 2910a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 'disallowed for security reasons' 2920a8c90248264a8b26970b4473770bcc3df8515fJosh Gao ) 2930a8c90248264a8b26970b4473770bcc3df8515fJosh Gao return AuthenticationString, (bytes(self),) 2940a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 2950a8c90248264a8b26970b4473770bcc3df8515fJosh Gao# 2960a8c90248264a8b26970b4473770bcc3df8515fJosh Gao# Create object representing the main process 2970a8c90248264a8b26970b4473770bcc3df8515fJosh Gao# 2980a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 2990a8c90248264a8b26970b4473770bcc3df8515fJosh Gaoclass _MainProcess(Process): 3000a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 3010a8c90248264a8b26970b4473770bcc3df8515fJosh Gao def __init__(self): 3020a8c90248264a8b26970b4473770bcc3df8515fJosh Gao self._identity = () 3030a8c90248264a8b26970b4473770bcc3df8515fJosh Gao self._daemonic = False 3040a8c90248264a8b26970b4473770bcc3df8515fJosh Gao self._name = 'MainProcess' 3050a8c90248264a8b26970b4473770bcc3df8515fJosh Gao self._parent_pid = None 3060a8c90248264a8b26970b4473770bcc3df8515fJosh Gao self._popen = None 3070a8c90248264a8b26970b4473770bcc3df8515fJosh Gao self._counter = itertools.count(1) 3080a8c90248264a8b26970b4473770bcc3df8515fJosh Gao self._children = set() 3090a8c90248264a8b26970b4473770bcc3df8515fJosh Gao self._authkey = AuthenticationString(os.urandom(32)) 3100a8c90248264a8b26970b4473770bcc3df8515fJosh Gao self._tempdir = None 3110a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 3120a8c90248264a8b26970b4473770bcc3df8515fJosh Gao_current_process = _MainProcess() 3130a8c90248264a8b26970b4473770bcc3df8515fJosh Gaodel _MainProcess 3140a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 3150a8c90248264a8b26970b4473770bcc3df8515fJosh Gao# 3160a8c90248264a8b26970b4473770bcc3df8515fJosh Gao# Give names to some return codes 3170a8c90248264a8b26970b4473770bcc3df8515fJosh Gao# 3180a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 3190a8c90248264a8b26970b4473770bcc3df8515fJosh Gao_exitcode_to_name = {} 3200a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 3210a8c90248264a8b26970b4473770bcc3df8515fJosh Gaofor name, signum in signal.__dict__.items(): 3220a8c90248264a8b26970b4473770bcc3df8515fJosh Gao if name[:3]=='SIG' and '_' not in name: 3230a8c90248264a8b26970b4473770bcc3df8515fJosh Gao _exitcode_to_name[-signum] = name 324