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:
Antoine Pitrou 2016-12-10 17:13:16 +01:00
parent 7a44783b42
commit cd2a201e5b
5 changed files with 37 additions and 2 deletions

View File

@ -195,7 +195,7 @@ class BaseContext(object):
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):

View File

@ -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'])

View File

@ -3728,6 +3728,19 @@ class TestStartMethod(unittest.TestCase):
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
View 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()

View File

@ -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.