mirror of
				https://github.com/python/cpython.git
				synced 2025-10-31 13:41:24 +00:00 
			
		
		
		
	
		
			
	
	
		
			76 lines
		
	
	
	
		
			2 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
		
		
			
		
	
	
			76 lines
		
	
	
	
		
			2 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
|   | import fcntl | ||
|  | import io | ||
|  | import os | ||
|  | 
 | ||
|  | from . import popen | ||
|  | from . import popen_fork | ||
|  | from . import reduction | ||
|  | from . import spawn | ||
|  | from . import util | ||
|  | 
 | ||
|  | from . import current_process | ||
|  | 
 | ||
|  | __all__ = ['Popen'] | ||
|  | 
 | ||
|  | 
 | ||
|  | # | ||
|  | # Wrapper for an fd used while launching a process | ||
|  | # | ||
|  | 
 | ||
|  | class _DupFd(object): | ||
|  |     def __init__(self, fd): | ||
|  |         self.fd = fd | ||
|  |     def detach(self): | ||
|  |         return self.fd | ||
|  | 
 | ||
|  | # | ||
|  | # Start child process using a fresh interpreter | ||
|  | # | ||
|  | 
 | ||
|  | class Popen(popen_fork.Popen): | ||
|  |     method = 'spawn' | ||
|  |     DupFd = _DupFd | ||
|  | 
 | ||
|  |     def __init__(self, process_obj): | ||
|  |         self._fds = [] | ||
|  |         super().__init__(process_obj) | ||
|  | 
 | ||
|  |     def duplicate_for_child(self, fd): | ||
|  |         self._fds.append(fd) | ||
|  |         return fd | ||
|  | 
 | ||
|  |     def _launch(self, process_obj): | ||
|  |         tracker_fd = current_process()._config['semaphore_tracker_fd'] | ||
|  |         self._fds.append(tracker_fd) | ||
|  |         prep_data = spawn.get_preparation_data(process_obj._name) | ||
|  |         fp = io.BytesIO() | ||
|  |         popen.set_spawning_popen(self) | ||
|  |         try: | ||
|  |             reduction.dump(prep_data, fp) | ||
|  |             reduction.dump(process_obj, fp) | ||
|  |         finally: | ||
|  |             popen.set_spawning_popen(None) | ||
|  | 
 | ||
|  |         parent_r = child_w = child_r = parent_w = None | ||
|  |         try: | ||
|  |             parent_r, child_w = util.pipe() | ||
|  |             child_r, parent_w = util.pipe() | ||
|  |             cmd = spawn.get_command_line() + [str(child_r)] | ||
|  |             self._fds.extend([child_r, child_w]) | ||
|  |             self.pid = util.spawnv_passfds(spawn.get_executable(), | ||
|  |                                            cmd, self._fds) | ||
|  |             self.sentinel = parent_r | ||
|  |             with open(parent_w, 'wb', closefd=False) as f: | ||
|  |                 f.write(fp.getbuffer()) | ||
|  |         finally: | ||
|  |             if parent_r is not None: | ||
|  |                 util.Finalize(self, os.close, (parent_r,)) | ||
|  |             for fd in (child_r, child_w, parent_w): | ||
|  |                 if fd is not None: | ||
|  |                     os.close(fd) | ||
|  | 
 | ||
|  |     @staticmethod | ||
|  |     def ensure_helpers_running(): | ||
|  |         from . import semaphore_tracker | ||
|  |         semaphore_tracker.ensure_running() |