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:19:21 +01:00
commit 5c7198d464
5 changed files with 37 additions and 2 deletions

View file

@ -196,7 +196,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')
@property @property

View file

@ -217,7 +217,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

@ -3818,6 +3818,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

@ -171,6 +171,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 #26937: The chown() method of the tarfile.TarFile class does not fail - Issue #26937: The chown() method of the tarfile.TarFile class does not fail
now when the grp module cannot be imported, as for example on Android now when the grp module cannot be imported, as for example on Android
platforms. platforms.