mirror of
				https://github.com/python/cpython.git
				synced 2025-10-30 21:21:22 +00:00 
			
		
		
		
	Issue #28779: multiprocessing.set_forkserver_preload() would crash the forkserver process if a preloaded module instantiated some multiprocessing objects such as locks.
This commit is contained in:
		
							parent
							
								
									7a44783b42
								
							
						
					
					
						commit
						cd2a201e5b
					
				
					 5 changed files with 37 additions and 2 deletions
				
			
		|  | @ -195,7 +195,7 @@ def get_context(self, method=None): | ||||||
|     def get_start_method(self, allow_none=False): |     def get_start_method(self, allow_none=False): | ||||||
|         return self._name |         return self._name | ||||||
| 
 | 
 | ||||||
|     def set_start_method(self, method=None): |     def set_start_method(self, method, force=False): | ||||||
|         raise ValueError('cannot set start method of concrete context') |         raise ValueError('cannot set start method of concrete context') | ||||||
| 
 | 
 | ||||||
|     def _check_available(self): |     def _check_available(self): | ||||||
|  |  | ||||||
|  | @ -218,7 +218,7 @@ def prepare(data): | ||||||
|         process.ORIGINAL_DIR = data['orig_dir'] |         process.ORIGINAL_DIR = data['orig_dir'] | ||||||
| 
 | 
 | ||||||
|     if 'start_method' in data: |     if 'start_method' in data: | ||||||
|         set_start_method(data['start_method']) |         set_start_method(data['start_method'], force=True) | ||||||
| 
 | 
 | ||||||
|     if 'init_main_from_name' in data: |     if 'init_main_from_name' in data: | ||||||
|         _fixup_main_from_name(data['init_main_from_name']) |         _fixup_main_from_name(data['init_main_from_name']) | ||||||
|  |  | ||||||
|  | @ -3728,6 +3728,19 @@ def test_get_all(self): | ||||||
|             self.assertTrue(methods == ['fork', 'spawn'] or |             self.assertTrue(methods == ['fork', 'spawn'] or | ||||||
|                             methods == ['fork', 'spawn', 'forkserver']) |                             methods == ['fork', 'spawn', 'forkserver']) | ||||||
| 
 | 
 | ||||||
|  |     def test_preload_resources(self): | ||||||
|  |         if multiprocessing.get_start_method() != 'forkserver': | ||||||
|  |             self.skipTest("test only relevant for 'forkserver' method") | ||||||
|  |         name = os.path.join(os.path.dirname(__file__), 'mp_preload.py') | ||||||
|  |         rc, out, err = test.support.script_helper.assert_python_ok(name) | ||||||
|  |         out = out.decode() | ||||||
|  |         err = err.decode() | ||||||
|  |         if out.rstrip() != 'ok' or err != '': | ||||||
|  |             print(out) | ||||||
|  |             print(err) | ||||||
|  |             self.fail("failed spawning forkserver or grandchild") | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
| # | # | ||||||
| # Check that killing process does not leak named semaphores | # Check that killing process does not leak named semaphores | ||||||
| # | # | ||||||
|  |  | ||||||
							
								
								
									
										18
									
								
								Lib/test/mp_preload.py
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										18
									
								
								Lib/test/mp_preload.py
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,18 @@ | ||||||
|  | import multiprocessing | ||||||
|  | 
 | ||||||
|  | multiprocessing.Lock() | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | def f(): | ||||||
|  |     print("ok") | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | if __name__ == "__main__": | ||||||
|  |     ctx = multiprocessing.get_context("forkserver") | ||||||
|  |     modname = "test.mp_preload" | ||||||
|  |     # Make sure it's importable | ||||||
|  |     __import__(modname) | ||||||
|  |     ctx.set_forkserver_preload([modname]) | ||||||
|  |     proc = ctx.Process(target=f) | ||||||
|  |     proc.start() | ||||||
|  |     proc.join() | ||||||
|  | @ -124,6 +124,10 @@ Core and Builtins | ||||||
| Library | Library | ||||||
| ------- | ------- | ||||||
| 
 | 
 | ||||||
|  | - Issue #28779: multiprocessing.set_forkserver_preload() would crash the | ||||||
|  |   forkserver process if a preloaded module instantiated some | ||||||
|  |   multiprocessing objects such as locks. | ||||||
|  | 
 | ||||||
| - Issue #28847: dbm.dumb now supports reading read-only files and no longer | - Issue #28847: dbm.dumb now supports reading read-only files and no longer | ||||||
|   writes the index file when it is not changed. |   writes the index file when it is not changed. | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Antoine Pitrou
						Antoine Pitrou