Make sure that a fork server is running. This can be called from any process. Note that usually a child process will just reuse the forkserver started by its parent, so ensure_running() will do nothing.
(self)
| 104 | os.close(child_w) |
| 105 | |
| 106 | def ensure_running(self): |
| 107 | '''Make sure that a fork server is running. |
| 108 | |
| 109 | This can be called from any process. Note that usually a child |
| 110 | process will just reuse the forkserver started by its parent, so |
| 111 | ensure_running() will do nothing. |
| 112 | ''' |
| 113 | with self._lock: |
| 114 | resource_tracker.ensure_running() |
| 115 | if self._forkserver_pid is not None: |
| 116 | # forkserver was launched before, is it still running? |
| 117 | pid, status = os.waitpid(self._forkserver_pid, os.WNOHANG) |
| 118 | if not pid: |
| 119 | # still alive |
| 120 | return |
| 121 | # dead, launch it again |
| 122 | os.close(self._forkserver_alive_fd) |
| 123 | self._forkserver_address = None |
| 124 | self._forkserver_alive_fd = None |
| 125 | self._forkserver_pid = None |
| 126 | |
| 127 | cmd = ('from multiprocessing.forkserver import main; ' + |
| 128 | 'main(%d, %d, %r, **%r)') |
| 129 | |
| 130 | main_kws = {} |
| 131 | if self._preload_modules: |
| 132 | data = spawn.get_preparation_data('ignore') |
| 133 | if 'sys_path' in data: |
| 134 | main_kws['sys_path'] = data['sys_path'] |
| 135 | if 'init_main_from_path' in data: |
| 136 | main_kws['main_path'] = data['init_main_from_path'] |
| 137 | |
| 138 | with socket.socket(socket.AF_UNIX) as listener: |
| 139 | address = connection.arbitrary_address('AF_UNIX') |
| 140 | listener.bind(address) |
| 141 | if not util.is_abstract_socket_namespace(address): |
| 142 | os.chmod(address, 0o600) |
| 143 | listener.listen() |
| 144 | |
| 145 | # all client processes own the write end of the "alive" pipe; |
| 146 | # when they all terminate the read end becomes ready. |
| 147 | alive_r, alive_w = os.pipe() |
| 148 | try: |
| 149 | fds_to_pass = [listener.fileno(), alive_r] |
| 150 | cmd %= (listener.fileno(), alive_r, self._preload_modules, |
| 151 | main_kws) |
| 152 | exe = spawn.get_executable() |
| 153 | args = [exe] + util._args_from_interpreter_flags() |
| 154 | args += ['-c', cmd] |
| 155 | pid = util.spawnv_passfds(exe, args, fds_to_pass) |
| 156 | except: |
| 157 | os.close(alive_w) |
| 158 | raise |
| 159 | finally: |
| 160 | os.close(alive_r) |
| 161 | self._forkserver_address = address |
| 162 | self._forkserver_alive_fd = alive_w |
| 163 | self._forkserver_pid = pid |