summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAntoine Pitrou <solipsis@pitrou.net>2016-12-10 16:19:21 (GMT)
committerAntoine Pitrou <solipsis@pitrou.net>2016-12-10 16:19:21 (GMT)
commit5c7198d46417cad8ca031b3d6a9d97c2ee6a1807 (patch)
tree5e74dd470decd388f0f125e63dceda99dc174d2e
parentc1a26a2e473efd3ff7a9cca5be75959384c41b8c (diff)
parentebb39bcc048b33d529a64f517ccee1c172ff8b07 (diff)
downloadcpython-5c7198d46417cad8ca031b3d6a9d97c2ee6a1807.zip
cpython-5c7198d46417cad8ca031b3d6a9d97c2ee6a1807.tar.gz
cpython-5c7198d46417cad8ca031b3d6a9d97c2ee6a1807.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.py2
-rw-r--r--Lib/multiprocessing/spawn.py2
-rw-r--r--Lib/test/_test_multiprocessing.py13
-rw-r--r--Lib/test/mp_preload.py18
-rw-r--r--Misc/NEWS4
5 files changed, 37 insertions, 2 deletions
diff --git a/Lib/multiprocessing/context.py b/Lib/multiprocessing/context.py
index 09455e2..623f6fb 100644
--- a/Lib/multiprocessing/context.py
+++ b/Lib/multiprocessing/context.py
@@ -196,7 +196,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')
@property
diff --git a/Lib/multiprocessing/spawn.py b/Lib/multiprocessing/spawn.py
index dfb9f65..4aba372 100644
--- a/Lib/multiprocessing/spawn.py
+++ b/Lib/multiprocessing/spawn.py
@@ -217,7 +217,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 c00846c..b5f4782 100644
--- a/Lib/test/_test_multiprocessing.py
+++ b/Lib/test/_test_multiprocessing.py
@@ -3818,6 +3818,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()
diff --git a/Misc/NEWS b/Misc/NEWS
index 48ce4bd..7358713 100644
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -171,6 +171,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 #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.