mirror of
				https://github.com/python/cpython.git
				synced 2025-10-30 21:21:22 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			75 lines
		
	
	
	
		
			2 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
			
		
		
	
	
			75 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()
 | 
