diff options
author | Antoine Pitrou <solipsis@pitrou.net> | 2016-12-10 16:13:16 (GMT) |
---|---|---|
committer | Antoine Pitrou <solipsis@pitrou.net> | 2016-12-10 16:13:16 (GMT) |
commit | cd2a201e5bb33c9b44401a91e10189be87885efe (patch) | |
tree | 9dee87e322d960ada1c61a24aabe9408ea3e9db6 | |
parent | 7a44783b425ed810cf38e48b43fb3800e2995fa1 (diff) | |
download | cpython-cd2a201e5bb33c9b44401a91e10189be87885efe.zip cpython-cd2a201e5bb33c9b44401a91e10189be87885efe.tar.gz cpython-cd2a201e5bb33c9b44401a91e10189be87885efe.tar.bz2 |
Issue #28779: multiprocessing.set_forkserver_preload() would crash the forkserver process if a preloaded module instantiated some multiprocessing objects such as locks.
-rw-r--r-- | Lib/multiprocessing/context.py | 2 | ||||
-rw-r--r-- | Lib/multiprocessing/spawn.py | 2 | ||||
-rw-r--r-- | Lib/test/_test_multiprocessing.py | 13 | ||||
-rw-r--r-- | Lib/test/mp_preload.py | 18 | ||||
-rw-r--r-- | Misc/NEWS | 4 |
5 files changed, 37 insertions, 2 deletions
diff --git a/Lib/multiprocessing/context.py b/Lib/multiprocessing/context.py index 63849f9..115d4bf 100644 --- a/Lib/multiprocessing/context.py +++ b/Lib/multiprocessing/context.py @@ -195,7 +195,7 @@ class BaseContext(object): def get_start_method(self, allow_none=False): 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') def _check_available(self): diff --git a/Lib/multiprocessing/spawn.py b/Lib/multiprocessing/spawn.py index 4d76951..392c1599 100644 --- a/Lib/multiprocessing/spawn.py +++ b/Lib/multiprocessing/spawn.py @@ -218,7 +218,7 @@ def prepare(data): process.ORIGINAL_DIR = data['orig_dir'] 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: _fixup_main_from_name(data['init_main_from_name']) diff --git a/Lib/test/_test_multiprocessing.py b/Lib/test/_test_multiprocessing.py index 2becfaa..9b789c2 100644 --- a/Lib/test/_test_multiprocessing.py +++ b/Lib/test/_test_multiprocessing.py @@ -3728,6 +3728,19 @@ class TestStartMethod(unittest.TestCase): self.assertTrue(methods == ['fork', 'spawn'] or 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 # diff --git a/Lib/test/mp_preload.py b/Lib/test/mp_preload.py new file mode 100644 index 0000000..5314e8f --- /dev/null +++ b/Lib/test/mp_preload.py @@ -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 ------- +- 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 writes the index file when it is not changed. |