1*cda5da8dSAndroid Build Coastguard Workerimport os 2*cda5da8dSAndroid Build Coastguard Workerimport sys 3*cda5da8dSAndroid Build Coastguard Workerimport threading 4*cda5da8dSAndroid Build Coastguard Worker 5*cda5da8dSAndroid Build Coastguard Workerfrom . import process 6*cda5da8dSAndroid Build Coastguard Workerfrom . import reduction 7*cda5da8dSAndroid Build Coastguard Worker 8*cda5da8dSAndroid Build Coastguard Worker__all__ = () 9*cda5da8dSAndroid Build Coastguard Worker 10*cda5da8dSAndroid Build Coastguard Worker# 11*cda5da8dSAndroid Build Coastguard Worker# Exceptions 12*cda5da8dSAndroid Build Coastguard Worker# 13*cda5da8dSAndroid Build Coastguard Worker 14*cda5da8dSAndroid Build Coastguard Workerclass ProcessError(Exception): 15*cda5da8dSAndroid Build Coastguard Worker pass 16*cda5da8dSAndroid Build Coastguard Worker 17*cda5da8dSAndroid Build Coastguard Workerclass BufferTooShort(ProcessError): 18*cda5da8dSAndroid Build Coastguard Worker pass 19*cda5da8dSAndroid Build Coastguard Worker 20*cda5da8dSAndroid Build Coastguard Workerclass TimeoutError(ProcessError): 21*cda5da8dSAndroid Build Coastguard Worker pass 22*cda5da8dSAndroid Build Coastguard Worker 23*cda5da8dSAndroid Build Coastguard Workerclass AuthenticationError(ProcessError): 24*cda5da8dSAndroid Build Coastguard Worker pass 25*cda5da8dSAndroid Build Coastguard Worker 26*cda5da8dSAndroid Build Coastguard Worker# 27*cda5da8dSAndroid Build Coastguard Worker# Base type for contexts. Bound methods of an instance of this type are included in __all__ of __init__.py 28*cda5da8dSAndroid Build Coastguard Worker# 29*cda5da8dSAndroid Build Coastguard Worker 30*cda5da8dSAndroid Build Coastguard Workerclass BaseContext(object): 31*cda5da8dSAndroid Build Coastguard Worker 32*cda5da8dSAndroid Build Coastguard Worker ProcessError = ProcessError 33*cda5da8dSAndroid Build Coastguard Worker BufferTooShort = BufferTooShort 34*cda5da8dSAndroid Build Coastguard Worker TimeoutError = TimeoutError 35*cda5da8dSAndroid Build Coastguard Worker AuthenticationError = AuthenticationError 36*cda5da8dSAndroid Build Coastguard Worker 37*cda5da8dSAndroid Build Coastguard Worker current_process = staticmethod(process.current_process) 38*cda5da8dSAndroid Build Coastguard Worker parent_process = staticmethod(process.parent_process) 39*cda5da8dSAndroid Build Coastguard Worker active_children = staticmethod(process.active_children) 40*cda5da8dSAndroid Build Coastguard Worker 41*cda5da8dSAndroid Build Coastguard Worker def cpu_count(self): 42*cda5da8dSAndroid Build Coastguard Worker '''Returns the number of CPUs in the system''' 43*cda5da8dSAndroid Build Coastguard Worker num = os.cpu_count() 44*cda5da8dSAndroid Build Coastguard Worker if num is None: 45*cda5da8dSAndroid Build Coastguard Worker raise NotImplementedError('cannot determine number of cpus') 46*cda5da8dSAndroid Build Coastguard Worker else: 47*cda5da8dSAndroid Build Coastguard Worker return num 48*cda5da8dSAndroid Build Coastguard Worker 49*cda5da8dSAndroid Build Coastguard Worker def Manager(self): 50*cda5da8dSAndroid Build Coastguard Worker '''Returns a manager associated with a running server process 51*cda5da8dSAndroid Build Coastguard Worker 52*cda5da8dSAndroid Build Coastguard Worker The managers methods such as `Lock()`, `Condition()` and `Queue()` 53*cda5da8dSAndroid Build Coastguard Worker can be used to create shared objects. 54*cda5da8dSAndroid Build Coastguard Worker ''' 55*cda5da8dSAndroid Build Coastguard Worker from .managers import SyncManager 56*cda5da8dSAndroid Build Coastguard Worker m = SyncManager(ctx=self.get_context()) 57*cda5da8dSAndroid Build Coastguard Worker m.start() 58*cda5da8dSAndroid Build Coastguard Worker return m 59*cda5da8dSAndroid Build Coastguard Worker 60*cda5da8dSAndroid Build Coastguard Worker def Pipe(self, duplex=True): 61*cda5da8dSAndroid Build Coastguard Worker '''Returns two connection object connected by a pipe''' 62*cda5da8dSAndroid Build Coastguard Worker from .connection import Pipe 63*cda5da8dSAndroid Build Coastguard Worker return Pipe(duplex) 64*cda5da8dSAndroid Build Coastguard Worker 65*cda5da8dSAndroid Build Coastguard Worker def Lock(self): 66*cda5da8dSAndroid Build Coastguard Worker '''Returns a non-recursive lock object''' 67*cda5da8dSAndroid Build Coastguard Worker from .synchronize import Lock 68*cda5da8dSAndroid Build Coastguard Worker return Lock(ctx=self.get_context()) 69*cda5da8dSAndroid Build Coastguard Worker 70*cda5da8dSAndroid Build Coastguard Worker def RLock(self): 71*cda5da8dSAndroid Build Coastguard Worker '''Returns a recursive lock object''' 72*cda5da8dSAndroid Build Coastguard Worker from .synchronize import RLock 73*cda5da8dSAndroid Build Coastguard Worker return RLock(ctx=self.get_context()) 74*cda5da8dSAndroid Build Coastguard Worker 75*cda5da8dSAndroid Build Coastguard Worker def Condition(self, lock=None): 76*cda5da8dSAndroid Build Coastguard Worker '''Returns a condition object''' 77*cda5da8dSAndroid Build Coastguard Worker from .synchronize import Condition 78*cda5da8dSAndroid Build Coastguard Worker return Condition(lock, ctx=self.get_context()) 79*cda5da8dSAndroid Build Coastguard Worker 80*cda5da8dSAndroid Build Coastguard Worker def Semaphore(self, value=1): 81*cda5da8dSAndroid Build Coastguard Worker '''Returns a semaphore object''' 82*cda5da8dSAndroid Build Coastguard Worker from .synchronize import Semaphore 83*cda5da8dSAndroid Build Coastguard Worker return Semaphore(value, ctx=self.get_context()) 84*cda5da8dSAndroid Build Coastguard Worker 85*cda5da8dSAndroid Build Coastguard Worker def BoundedSemaphore(self, value=1): 86*cda5da8dSAndroid Build Coastguard Worker '''Returns a bounded semaphore object''' 87*cda5da8dSAndroid Build Coastguard Worker from .synchronize import BoundedSemaphore 88*cda5da8dSAndroid Build Coastguard Worker return BoundedSemaphore(value, ctx=self.get_context()) 89*cda5da8dSAndroid Build Coastguard Worker 90*cda5da8dSAndroid Build Coastguard Worker def Event(self): 91*cda5da8dSAndroid Build Coastguard Worker '''Returns an event object''' 92*cda5da8dSAndroid Build Coastguard Worker from .synchronize import Event 93*cda5da8dSAndroid Build Coastguard Worker return Event(ctx=self.get_context()) 94*cda5da8dSAndroid Build Coastguard Worker 95*cda5da8dSAndroid Build Coastguard Worker def Barrier(self, parties, action=None, timeout=None): 96*cda5da8dSAndroid Build Coastguard Worker '''Returns a barrier object''' 97*cda5da8dSAndroid Build Coastguard Worker from .synchronize import Barrier 98*cda5da8dSAndroid Build Coastguard Worker return Barrier(parties, action, timeout, ctx=self.get_context()) 99*cda5da8dSAndroid Build Coastguard Worker 100*cda5da8dSAndroid Build Coastguard Worker def Queue(self, maxsize=0): 101*cda5da8dSAndroid Build Coastguard Worker '''Returns a queue object''' 102*cda5da8dSAndroid Build Coastguard Worker from .queues import Queue 103*cda5da8dSAndroid Build Coastguard Worker return Queue(maxsize, ctx=self.get_context()) 104*cda5da8dSAndroid Build Coastguard Worker 105*cda5da8dSAndroid Build Coastguard Worker def JoinableQueue(self, maxsize=0): 106*cda5da8dSAndroid Build Coastguard Worker '''Returns a queue object''' 107*cda5da8dSAndroid Build Coastguard Worker from .queues import JoinableQueue 108*cda5da8dSAndroid Build Coastguard Worker return JoinableQueue(maxsize, ctx=self.get_context()) 109*cda5da8dSAndroid Build Coastguard Worker 110*cda5da8dSAndroid Build Coastguard Worker def SimpleQueue(self): 111*cda5da8dSAndroid Build Coastguard Worker '''Returns a queue object''' 112*cda5da8dSAndroid Build Coastguard Worker from .queues import SimpleQueue 113*cda5da8dSAndroid Build Coastguard Worker return SimpleQueue(ctx=self.get_context()) 114*cda5da8dSAndroid Build Coastguard Worker 115*cda5da8dSAndroid Build Coastguard Worker def Pool(self, processes=None, initializer=None, initargs=(), 116*cda5da8dSAndroid Build Coastguard Worker maxtasksperchild=None): 117*cda5da8dSAndroid Build Coastguard Worker '''Returns a process pool object''' 118*cda5da8dSAndroid Build Coastguard Worker from .pool import Pool 119*cda5da8dSAndroid Build Coastguard Worker return Pool(processes, initializer, initargs, maxtasksperchild, 120*cda5da8dSAndroid Build Coastguard Worker context=self.get_context()) 121*cda5da8dSAndroid Build Coastguard Worker 122*cda5da8dSAndroid Build Coastguard Worker def RawValue(self, typecode_or_type, *args): 123*cda5da8dSAndroid Build Coastguard Worker '''Returns a shared object''' 124*cda5da8dSAndroid Build Coastguard Worker from .sharedctypes import RawValue 125*cda5da8dSAndroid Build Coastguard Worker return RawValue(typecode_or_type, *args) 126*cda5da8dSAndroid Build Coastguard Worker 127*cda5da8dSAndroid Build Coastguard Worker def RawArray(self, typecode_or_type, size_or_initializer): 128*cda5da8dSAndroid Build Coastguard Worker '''Returns a shared array''' 129*cda5da8dSAndroid Build Coastguard Worker from .sharedctypes import RawArray 130*cda5da8dSAndroid Build Coastguard Worker return RawArray(typecode_or_type, size_or_initializer) 131*cda5da8dSAndroid Build Coastguard Worker 132*cda5da8dSAndroid Build Coastguard Worker def Value(self, typecode_or_type, *args, lock=True): 133*cda5da8dSAndroid Build Coastguard Worker '''Returns a synchronized shared object''' 134*cda5da8dSAndroid Build Coastguard Worker from .sharedctypes import Value 135*cda5da8dSAndroid Build Coastguard Worker return Value(typecode_or_type, *args, lock=lock, 136*cda5da8dSAndroid Build Coastguard Worker ctx=self.get_context()) 137*cda5da8dSAndroid Build Coastguard Worker 138*cda5da8dSAndroid Build Coastguard Worker def Array(self, typecode_or_type, size_or_initializer, *, lock=True): 139*cda5da8dSAndroid Build Coastguard Worker '''Returns a synchronized shared array''' 140*cda5da8dSAndroid Build Coastguard Worker from .sharedctypes import Array 141*cda5da8dSAndroid Build Coastguard Worker return Array(typecode_or_type, size_or_initializer, lock=lock, 142*cda5da8dSAndroid Build Coastguard Worker ctx=self.get_context()) 143*cda5da8dSAndroid Build Coastguard Worker 144*cda5da8dSAndroid Build Coastguard Worker def freeze_support(self): 145*cda5da8dSAndroid Build Coastguard Worker '''Check whether this is a fake forked process in a frozen executable. 146*cda5da8dSAndroid Build Coastguard Worker If so then run code specified by commandline and exit. 147*cda5da8dSAndroid Build Coastguard Worker ''' 148*cda5da8dSAndroid Build Coastguard Worker if sys.platform == 'win32' and getattr(sys, 'frozen', False): 149*cda5da8dSAndroid Build Coastguard Worker from .spawn import freeze_support 150*cda5da8dSAndroid Build Coastguard Worker freeze_support() 151*cda5da8dSAndroid Build Coastguard Worker 152*cda5da8dSAndroid Build Coastguard Worker def get_logger(self): 153*cda5da8dSAndroid Build Coastguard Worker '''Return package logger -- if it does not already exist then 154*cda5da8dSAndroid Build Coastguard Worker it is created. 155*cda5da8dSAndroid Build Coastguard Worker ''' 156*cda5da8dSAndroid Build Coastguard Worker from .util import get_logger 157*cda5da8dSAndroid Build Coastguard Worker return get_logger() 158*cda5da8dSAndroid Build Coastguard Worker 159*cda5da8dSAndroid Build Coastguard Worker def log_to_stderr(self, level=None): 160*cda5da8dSAndroid Build Coastguard Worker '''Turn on logging and add a handler which prints to stderr''' 161*cda5da8dSAndroid Build Coastguard Worker from .util import log_to_stderr 162*cda5da8dSAndroid Build Coastguard Worker return log_to_stderr(level) 163*cda5da8dSAndroid Build Coastguard Worker 164*cda5da8dSAndroid Build Coastguard Worker def allow_connection_pickling(self): 165*cda5da8dSAndroid Build Coastguard Worker '''Install support for sending connections and sockets 166*cda5da8dSAndroid Build Coastguard Worker between processes 167*cda5da8dSAndroid Build Coastguard Worker ''' 168*cda5da8dSAndroid Build Coastguard Worker # This is undocumented. In previous versions of multiprocessing 169*cda5da8dSAndroid Build Coastguard Worker # its only effect was to make socket objects inheritable on Windows. 170*cda5da8dSAndroid Build Coastguard Worker from . import connection 171*cda5da8dSAndroid Build Coastguard Worker 172*cda5da8dSAndroid Build Coastguard Worker def set_executable(self, executable): 173*cda5da8dSAndroid Build Coastguard Worker '''Sets the path to a python.exe or pythonw.exe binary used to run 174*cda5da8dSAndroid Build Coastguard Worker child processes instead of sys.executable when using the 'spawn' 175*cda5da8dSAndroid Build Coastguard Worker start method. Useful for people embedding Python. 176*cda5da8dSAndroid Build Coastguard Worker ''' 177*cda5da8dSAndroid Build Coastguard Worker from .spawn import set_executable 178*cda5da8dSAndroid Build Coastguard Worker set_executable(executable) 179*cda5da8dSAndroid Build Coastguard Worker 180*cda5da8dSAndroid Build Coastguard Worker def set_forkserver_preload(self, module_names): 181*cda5da8dSAndroid Build Coastguard Worker '''Set list of module names to try to load in forkserver process. 182*cda5da8dSAndroid Build Coastguard Worker This is really just a hint. 183*cda5da8dSAndroid Build Coastguard Worker ''' 184*cda5da8dSAndroid Build Coastguard Worker from .forkserver import set_forkserver_preload 185*cda5da8dSAndroid Build Coastguard Worker set_forkserver_preload(module_names) 186*cda5da8dSAndroid Build Coastguard Worker 187*cda5da8dSAndroid Build Coastguard Worker def get_context(self, method=None): 188*cda5da8dSAndroid Build Coastguard Worker if method is None: 189*cda5da8dSAndroid Build Coastguard Worker return self 190*cda5da8dSAndroid Build Coastguard Worker try: 191*cda5da8dSAndroid Build Coastguard Worker ctx = _concrete_contexts[method] 192*cda5da8dSAndroid Build Coastguard Worker except KeyError: 193*cda5da8dSAndroid Build Coastguard Worker raise ValueError('cannot find context for %r' % method) from None 194*cda5da8dSAndroid Build Coastguard Worker ctx._check_available() 195*cda5da8dSAndroid Build Coastguard Worker return ctx 196*cda5da8dSAndroid Build Coastguard Worker 197*cda5da8dSAndroid Build Coastguard Worker def get_start_method(self, allow_none=False): 198*cda5da8dSAndroid Build Coastguard Worker return self._name 199*cda5da8dSAndroid Build Coastguard Worker 200*cda5da8dSAndroid Build Coastguard Worker def set_start_method(self, method, force=False): 201*cda5da8dSAndroid Build Coastguard Worker raise ValueError('cannot set start method of concrete context') 202*cda5da8dSAndroid Build Coastguard Worker 203*cda5da8dSAndroid Build Coastguard Worker @property 204*cda5da8dSAndroid Build Coastguard Worker def reducer(self): 205*cda5da8dSAndroid Build Coastguard Worker '''Controls how objects will be reduced to a form that can be 206*cda5da8dSAndroid Build Coastguard Worker shared with other processes.''' 207*cda5da8dSAndroid Build Coastguard Worker return globals().get('reduction') 208*cda5da8dSAndroid Build Coastguard Worker 209*cda5da8dSAndroid Build Coastguard Worker @reducer.setter 210*cda5da8dSAndroid Build Coastguard Worker def reducer(self, reduction): 211*cda5da8dSAndroid Build Coastguard Worker globals()['reduction'] = reduction 212*cda5da8dSAndroid Build Coastguard Worker 213*cda5da8dSAndroid Build Coastguard Worker def _check_available(self): 214*cda5da8dSAndroid Build Coastguard Worker pass 215*cda5da8dSAndroid Build Coastguard Worker 216*cda5da8dSAndroid Build Coastguard Worker# 217*cda5da8dSAndroid Build Coastguard Worker# Type of default context -- underlying context can be set at most once 218*cda5da8dSAndroid Build Coastguard Worker# 219*cda5da8dSAndroid Build Coastguard Worker 220*cda5da8dSAndroid Build Coastguard Workerclass Process(process.BaseProcess): 221*cda5da8dSAndroid Build Coastguard Worker _start_method = None 222*cda5da8dSAndroid Build Coastguard Worker @staticmethod 223*cda5da8dSAndroid Build Coastguard Worker def _Popen(process_obj): 224*cda5da8dSAndroid Build Coastguard Worker return _default_context.get_context().Process._Popen(process_obj) 225*cda5da8dSAndroid Build Coastguard Worker 226*cda5da8dSAndroid Build Coastguard Worker @staticmethod 227*cda5da8dSAndroid Build Coastguard Worker def _after_fork(): 228*cda5da8dSAndroid Build Coastguard Worker return _default_context.get_context().Process._after_fork() 229*cda5da8dSAndroid Build Coastguard Worker 230*cda5da8dSAndroid Build Coastguard Workerclass DefaultContext(BaseContext): 231*cda5da8dSAndroid Build Coastguard Worker Process = Process 232*cda5da8dSAndroid Build Coastguard Worker 233*cda5da8dSAndroid Build Coastguard Worker def __init__(self, context): 234*cda5da8dSAndroid Build Coastguard Worker self._default_context = context 235*cda5da8dSAndroid Build Coastguard Worker self._actual_context = None 236*cda5da8dSAndroid Build Coastguard Worker 237*cda5da8dSAndroid Build Coastguard Worker def get_context(self, method=None): 238*cda5da8dSAndroid Build Coastguard Worker if method is None: 239*cda5da8dSAndroid Build Coastguard Worker if self._actual_context is None: 240*cda5da8dSAndroid Build Coastguard Worker self._actual_context = self._default_context 241*cda5da8dSAndroid Build Coastguard Worker return self._actual_context 242*cda5da8dSAndroid Build Coastguard Worker else: 243*cda5da8dSAndroid Build Coastguard Worker return super().get_context(method) 244*cda5da8dSAndroid Build Coastguard Worker 245*cda5da8dSAndroid Build Coastguard Worker def set_start_method(self, method, force=False): 246*cda5da8dSAndroid Build Coastguard Worker if self._actual_context is not None and not force: 247*cda5da8dSAndroid Build Coastguard Worker raise RuntimeError('context has already been set') 248*cda5da8dSAndroid Build Coastguard Worker if method is None and force: 249*cda5da8dSAndroid Build Coastguard Worker self._actual_context = None 250*cda5da8dSAndroid Build Coastguard Worker return 251*cda5da8dSAndroid Build Coastguard Worker self._actual_context = self.get_context(method) 252*cda5da8dSAndroid Build Coastguard Worker 253*cda5da8dSAndroid Build Coastguard Worker def get_start_method(self, allow_none=False): 254*cda5da8dSAndroid Build Coastguard Worker if self._actual_context is None: 255*cda5da8dSAndroid Build Coastguard Worker if allow_none: 256*cda5da8dSAndroid Build Coastguard Worker return None 257*cda5da8dSAndroid Build Coastguard Worker self._actual_context = self._default_context 258*cda5da8dSAndroid Build Coastguard Worker return self._actual_context._name 259*cda5da8dSAndroid Build Coastguard Worker 260*cda5da8dSAndroid Build Coastguard Worker def get_all_start_methods(self): 261*cda5da8dSAndroid Build Coastguard Worker if sys.platform == 'win32': 262*cda5da8dSAndroid Build Coastguard Worker return ['spawn'] 263*cda5da8dSAndroid Build Coastguard Worker else: 264*cda5da8dSAndroid Build Coastguard Worker methods = ['spawn', 'fork'] if sys.platform == 'darwin' else ['fork', 'spawn'] 265*cda5da8dSAndroid Build Coastguard Worker if reduction.HAVE_SEND_HANDLE: 266*cda5da8dSAndroid Build Coastguard Worker methods.append('forkserver') 267*cda5da8dSAndroid Build Coastguard Worker return methods 268*cda5da8dSAndroid Build Coastguard Worker 269*cda5da8dSAndroid Build Coastguard Worker 270*cda5da8dSAndroid Build Coastguard Worker# 271*cda5da8dSAndroid Build Coastguard Worker# Context types for fixed start method 272*cda5da8dSAndroid Build Coastguard Worker# 273*cda5da8dSAndroid Build Coastguard Worker 274*cda5da8dSAndroid Build Coastguard Workerif sys.platform != 'win32': 275*cda5da8dSAndroid Build Coastguard Worker 276*cda5da8dSAndroid Build Coastguard Worker class ForkProcess(process.BaseProcess): 277*cda5da8dSAndroid Build Coastguard Worker _start_method = 'fork' 278*cda5da8dSAndroid Build Coastguard Worker @staticmethod 279*cda5da8dSAndroid Build Coastguard Worker def _Popen(process_obj): 280*cda5da8dSAndroid Build Coastguard Worker from .popen_fork import Popen 281*cda5da8dSAndroid Build Coastguard Worker return Popen(process_obj) 282*cda5da8dSAndroid Build Coastguard Worker 283*cda5da8dSAndroid Build Coastguard Worker class SpawnProcess(process.BaseProcess): 284*cda5da8dSAndroid Build Coastguard Worker _start_method = 'spawn' 285*cda5da8dSAndroid Build Coastguard Worker @staticmethod 286*cda5da8dSAndroid Build Coastguard Worker def _Popen(process_obj): 287*cda5da8dSAndroid Build Coastguard Worker from .popen_spawn_posix import Popen 288*cda5da8dSAndroid Build Coastguard Worker return Popen(process_obj) 289*cda5da8dSAndroid Build Coastguard Worker 290*cda5da8dSAndroid Build Coastguard Worker @staticmethod 291*cda5da8dSAndroid Build Coastguard Worker def _after_fork(): 292*cda5da8dSAndroid Build Coastguard Worker # process is spawned, nothing to do 293*cda5da8dSAndroid Build Coastguard Worker pass 294*cda5da8dSAndroid Build Coastguard Worker 295*cda5da8dSAndroid Build Coastguard Worker class ForkServerProcess(process.BaseProcess): 296*cda5da8dSAndroid Build Coastguard Worker _start_method = 'forkserver' 297*cda5da8dSAndroid Build Coastguard Worker @staticmethod 298*cda5da8dSAndroid Build Coastguard Worker def _Popen(process_obj): 299*cda5da8dSAndroid Build Coastguard Worker from .popen_forkserver import Popen 300*cda5da8dSAndroid Build Coastguard Worker return Popen(process_obj) 301*cda5da8dSAndroid Build Coastguard Worker 302*cda5da8dSAndroid Build Coastguard Worker class ForkContext(BaseContext): 303*cda5da8dSAndroid Build Coastguard Worker _name = 'fork' 304*cda5da8dSAndroid Build Coastguard Worker Process = ForkProcess 305*cda5da8dSAndroid Build Coastguard Worker 306*cda5da8dSAndroid Build Coastguard Worker class SpawnContext(BaseContext): 307*cda5da8dSAndroid Build Coastguard Worker _name = 'spawn' 308*cda5da8dSAndroid Build Coastguard Worker Process = SpawnProcess 309*cda5da8dSAndroid Build Coastguard Worker 310*cda5da8dSAndroid Build Coastguard Worker class ForkServerContext(BaseContext): 311*cda5da8dSAndroid Build Coastguard Worker _name = 'forkserver' 312*cda5da8dSAndroid Build Coastguard Worker Process = ForkServerProcess 313*cda5da8dSAndroid Build Coastguard Worker def _check_available(self): 314*cda5da8dSAndroid Build Coastguard Worker if not reduction.HAVE_SEND_HANDLE: 315*cda5da8dSAndroid Build Coastguard Worker raise ValueError('forkserver start method not available') 316*cda5da8dSAndroid Build Coastguard Worker 317*cda5da8dSAndroid Build Coastguard Worker _concrete_contexts = { 318*cda5da8dSAndroid Build Coastguard Worker 'fork': ForkContext(), 319*cda5da8dSAndroid Build Coastguard Worker 'spawn': SpawnContext(), 320*cda5da8dSAndroid Build Coastguard Worker 'forkserver': ForkServerContext(), 321*cda5da8dSAndroid Build Coastguard Worker } 322*cda5da8dSAndroid Build Coastguard Worker if sys.platform == 'darwin': 323*cda5da8dSAndroid Build Coastguard Worker # bpo-33725: running arbitrary code after fork() is no longer reliable 324*cda5da8dSAndroid Build Coastguard Worker # on macOS since macOS 10.14 (Mojave). Use spawn by default instead. 325*cda5da8dSAndroid Build Coastguard Worker _default_context = DefaultContext(_concrete_contexts['spawn']) 326*cda5da8dSAndroid Build Coastguard Worker else: 327*cda5da8dSAndroid Build Coastguard Worker _default_context = DefaultContext(_concrete_contexts['fork']) 328*cda5da8dSAndroid Build Coastguard Worker 329*cda5da8dSAndroid Build Coastguard Workerelse: 330*cda5da8dSAndroid Build Coastguard Worker 331*cda5da8dSAndroid Build Coastguard Worker class SpawnProcess(process.BaseProcess): 332*cda5da8dSAndroid Build Coastguard Worker _start_method = 'spawn' 333*cda5da8dSAndroid Build Coastguard Worker @staticmethod 334*cda5da8dSAndroid Build Coastguard Worker def _Popen(process_obj): 335*cda5da8dSAndroid Build Coastguard Worker from .popen_spawn_win32 import Popen 336*cda5da8dSAndroid Build Coastguard Worker return Popen(process_obj) 337*cda5da8dSAndroid Build Coastguard Worker 338*cda5da8dSAndroid Build Coastguard Worker @staticmethod 339*cda5da8dSAndroid Build Coastguard Worker def _after_fork(): 340*cda5da8dSAndroid Build Coastguard Worker # process is spawned, nothing to do 341*cda5da8dSAndroid Build Coastguard Worker pass 342*cda5da8dSAndroid Build Coastguard Worker 343*cda5da8dSAndroid Build Coastguard Worker class SpawnContext(BaseContext): 344*cda5da8dSAndroid Build Coastguard Worker _name = 'spawn' 345*cda5da8dSAndroid Build Coastguard Worker Process = SpawnProcess 346*cda5da8dSAndroid Build Coastguard Worker 347*cda5da8dSAndroid Build Coastguard Worker _concrete_contexts = { 348*cda5da8dSAndroid Build Coastguard Worker 'spawn': SpawnContext(), 349*cda5da8dSAndroid Build Coastguard Worker } 350*cda5da8dSAndroid Build Coastguard Worker _default_context = DefaultContext(_concrete_contexts['spawn']) 351*cda5da8dSAndroid Build Coastguard Worker 352*cda5da8dSAndroid Build Coastguard Worker# 353*cda5da8dSAndroid Build Coastguard Worker# Force the start method 354*cda5da8dSAndroid Build Coastguard Worker# 355*cda5da8dSAndroid Build Coastguard Worker 356*cda5da8dSAndroid Build Coastguard Workerdef _force_start_method(method): 357*cda5da8dSAndroid Build Coastguard Worker _default_context._actual_context = _concrete_contexts[method] 358*cda5da8dSAndroid Build Coastguard Worker 359*cda5da8dSAndroid Build Coastguard Worker# 360*cda5da8dSAndroid Build Coastguard Worker# Check that the current thread is spawning a child process 361*cda5da8dSAndroid Build Coastguard Worker# 362*cda5da8dSAndroid Build Coastguard Worker 363*cda5da8dSAndroid Build Coastguard Worker_tls = threading.local() 364*cda5da8dSAndroid Build Coastguard Worker 365*cda5da8dSAndroid Build Coastguard Workerdef get_spawning_popen(): 366*cda5da8dSAndroid Build Coastguard Worker return getattr(_tls, 'spawning_popen', None) 367*cda5da8dSAndroid Build Coastguard Worker 368*cda5da8dSAndroid Build Coastguard Workerdef set_spawning_popen(popen): 369*cda5da8dSAndroid Build Coastguard Worker _tls.spawning_popen = popen 370*cda5da8dSAndroid Build Coastguard Worker 371*cda5da8dSAndroid Build Coastguard Workerdef assert_spawning(obj): 372*cda5da8dSAndroid Build Coastguard Worker if get_spawning_popen() is None: 373*cda5da8dSAndroid Build Coastguard Worker raise RuntimeError( 374*cda5da8dSAndroid Build Coastguard Worker '%s objects should only be shared between processes' 375*cda5da8dSAndroid Build Coastguard Worker ' through inheritance' % type(obj).__name__ 376*cda5da8dSAndroid Build Coastguard Worker ) 377