Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.8/multiprocessing/popen_spawn_posix.py: 28%
50 statements
« prev ^ index » next coverage.py v7.0.1, created at 2022-12-25 06:11 +0000
« prev ^ index » next coverage.py v7.0.1, created at 2022-12-25 06:11 +0000
1import io
2import os
4from .context import reduction, set_spawning_popen
5from . import popen_fork
6from . import spawn
7from . import util
9__all__ = ['Popen']
12#
13# Wrapper for an fd used while launching a process
14#
16class _DupFd(object):
17 def __init__(self, fd):
18 self.fd = fd
19 def detach(self):
20 return self.fd
22#
23# Start child process using a fresh interpreter
24#
26class Popen(popen_fork.Popen):
27 method = 'spawn'
28 DupFd = _DupFd
30 def __init__(self, process_obj):
31 self._fds = []
32 super().__init__(process_obj)
34 def duplicate_for_child(self, fd):
35 self._fds.append(fd)
36 return fd
38 def _launch(self, process_obj):
39 from . import resource_tracker
40 tracker_fd = resource_tracker.getfd()
41 self._fds.append(tracker_fd)
42 prep_data = spawn.get_preparation_data(process_obj._name)
43 fp = io.BytesIO()
44 set_spawning_popen(self)
45 try:
46 reduction.dump(prep_data, fp)
47 reduction.dump(process_obj, fp)
48 finally:
49 set_spawning_popen(None)
51 parent_r = child_w = child_r = parent_w = None
52 try:
53 parent_r, child_w = os.pipe()
54 child_r, parent_w = os.pipe()
55 cmd = spawn.get_command_line(tracker_fd=tracker_fd,
56 pipe_handle=child_r)
57 self._fds.extend([child_r, child_w])
58 self.pid = util.spawnv_passfds(spawn.get_executable(),
59 cmd, self._fds)
60 self.sentinel = parent_r
61 with open(parent_w, 'wb', closefd=False) as f:
62 f.write(fp.getbuffer())
63 finally:
64 fds_to_close = []
65 for fd in (parent_r, parent_w):
66 if fd is not None:
67 fds_to_close.append(fd)
68 self.finalizer = util.Finalize(self, util.close_fds, fds_to_close)
70 for fd in (child_r, child_w):
71 if fd is not None:
72 os.close(fd)