Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit ebb39bc

Browse files
committed
Issue #28779: multiprocessing.set_forkserver_preload() would crash the forkserver process if a preloaded module instantiated some multiprocessing objects such as locks.
2 parents 13f1c33 + cd2a201 commit ebb39bc

5 files changed

Lines changed: 37 additions & 2 deletions

File tree

Lib/multiprocessing/context.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -196,7 +196,7 @@ def get_context(self, method=None):
196196
def get_start_method(self, allow_none=False):
197197
return self._name
198198

199-
def set_start_method(self, method=None):
199+
def set_start_method(self, method, force=False):
200200
raise ValueError('cannot set start method of concrete context')
201201

202202
@property

Lib/multiprocessing/spawn.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -217,7 +217,7 @@ def prepare(data):
217217
process.ORIGINAL_DIR = data['orig_dir']
218218

219219
if 'start_method' in data:
220-
set_start_method(data['start_method'])
220+
set_start_method(data['start_method'], force=True)
221221

222222
if 'init_main_from_name' in data:
223223
_fixup_main_from_name(data['init_main_from_name'])

Lib/test/_test_multiprocessing.py

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3818,6 +3818,19 @@ def test_get_all(self):
38183818
self.assertTrue(methods == ['fork', 'spawn'] or
38193819
methods == ['fork', 'spawn', 'forkserver'])
38203820

3821+
def test_preload_resources(self):
3822+
if multiprocessing.get_start_method() != 'forkserver':
3823+
self.skipTest("test only relevant for 'forkserver' method")
3824+
name = os.path.join(os.path.dirname(__file__), 'mp_preload.py')
3825+
rc, out, err = test.support.script_helper.assert_python_ok(name)
3826+
out = out.decode()
3827+
err = err.decode()
3828+
if out.rstrip() != 'ok' or err != '':
3829+
print(out)
3830+
print(err)
3831+
self.fail("failed spawning forkserver or grandchild")
3832+
3833+
38213834
#
38223835
# Check that killing process does not leak named semaphores
38233836
#

Lib/test/mp_preload.py

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
import multiprocessing
2+
3+
multiprocessing.Lock()
4+
5+
6+
def f():
7+
print("ok")
8+
9+
10+
if __name__ == "__main__":
11+
ctx = multiprocessing.get_context("forkserver")
12+
modname = "test.mp_preload"
13+
# Make sure it's importable
14+
__import__(modname)
15+
ctx.set_forkserver_preload([modname])
16+
proc = ctx.Process(target=f)
17+
proc.start()
18+
proc.join()

Misc/NEWS

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,10 @@ Core and Builtins
2222
Library
2323
-------
2424

25+
- Issue #28779: multiprocessing.set_forkserver_preload() would crash the
26+
forkserver process if a preloaded module instantiated some
27+
multiprocessing objects such as locks.
28+
2529
- Issue #28847: dbm.dumb now supports reading read-only files and no longer
2630
writes the index file when it is not changed.
2731

0 commit comments

Comments
 (0)