changeset: 105576:5456b699788f parent: 105573:ff82dfd558df parent: 105575:f3b9fd41b5cb user: Antoine Pitrou date: Sat Dec 10 17:19:21 2016 +0100 files: Misc/NEWS description: Issue #28779: multiprocessing.set_forkserver_preload() would crash the forkserver process if a preloaded module instantiated some multiprocessing objects such as locks. diff -r ff82dfd558df -r 5456b699788f Lib/multiprocessing/context.py --- a/Lib/multiprocessing/context.py Sat Dec 10 16:48:07 2016 +0100 +++ b/Lib/multiprocessing/context.py Sat Dec 10 17:19:21 2016 +0100 @@ -196,7 +196,7 @@ 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') @property diff -r ff82dfd558df -r 5456b699788f Lib/multiprocessing/spawn.py --- a/Lib/multiprocessing/spawn.py Sat Dec 10 16:48:07 2016 +0100 +++ b/Lib/multiprocessing/spawn.py Sat Dec 10 17:19:21 2016 +0100 @@ -217,7 +217,7 @@ 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 -r ff82dfd558df -r 5456b699788f Lib/test/_test_multiprocessing.py --- a/Lib/test/_test_multiprocessing.py Sat Dec 10 16:48:07 2016 +0100 +++ b/Lib/test/_test_multiprocessing.py Sat Dec 10 17:19:21 2016 +0100 @@ -3818,6 +3818,19 @@ 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 -r ff82dfd558df -r 5456b699788f Lib/test/mp_preload.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Lib/test/mp_preload.py Sat Dec 10 17:19:21 2016 +0100 @@ -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() diff -r ff82dfd558df -r 5456b699788f Misc/NEWS --- a/Misc/NEWS Sat Dec 10 16:48:07 2016 +0100 +++ b/Misc/NEWS Sat Dec 10 17:19:21 2016 +0100 @@ -171,6 +171,10 @@ 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 now when the grp module cannot be imported, as for example on Android platforms.