| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
1 parent 5d18715 commit 1700d34
3 files changed
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -50,8 +50,8 @@ class SemLock(object): | |||
| 50 | 50 | def __init__(self, kind, value, maxvalue, *, ctx): | |
| 51 | 51 | if ctx is None: | |
| 52 | 52 | ctx = context._default_context.get_context() | |
| 53 | - name = ctx.get_start_method() | ||
| 54 | - unlink_now = sys.platform == 'win32' or name == 'fork' | ||
| 53 | + self.is_fork_ctx = ctx.get_start_method() == 'fork' | ||
| 54 | + unlink_now = sys.platform == 'win32' or self.is_fork_ctx | ||
| 55 | 55 | for i in range(100): | |
| 56 | 56 | try: | |
| 57 | 57 | sl = self._semlock = _multiprocessing.SemLock( | |
@@ -103,6 +103,11 @@ def __getstate__(self): | |||
| 103 | 103 | if sys.platform == 'win32': | |
| 104 | 104 | h = context.get_spawning_popen().duplicate_for_child(sl.handle) | |
| 105 | 105 | else: | |
| 106 | + if self.is_fork_ctx: | ||
| 107 | + raise RuntimeError('A SemLock created in a fork context is being ' | ||
| 108 | + 'shared with a process in a spawn context. This is ' | ||
| 109 | + 'not supported. Please use the same context to create ' | ||
| 110 | + 'multiprocessing objects and Process.') | ||
| 106 | 111 | h = sl.handle | |
| 107 | 112 | return (h, sl.kind, sl.maxvalue, sl.name) | |
| 108 | 113 | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -5421,6 +5421,28 @@ def test_preload_resources(self): | |||
| 5421 | 5421 | print(err) | |
| 5422 | 5422 | self.fail("failed spawning forkserver or grandchild") | |
| 5423 | 5423 | ||
| 5424 | + @unittest.skipIf(sys.platform == "win32", | ||
| 5425 | + "Only Spawn on windows so no risk of mixing") | ||
| 5426 | + @only_run_in_spawn_testsuite("avoids redundant testing.") | ||
| 5427 | + def test_mixed_startmethod(self): | ||
| 5428 | + # Fork-based locks cannot be used with spawned process | ||
| 5429 | + for process_method in ["spawn", "forkserver"]: | ||
| 5430 | + queue = multiprocessing.get_context("fork").Queue() | ||
| 5431 | + process_ctx = multiprocessing.get_context(process_method) | ||
| 5432 | + p = process_ctx.Process(target=close_queue, args=(queue,)) | ||
| 5433 | + err_msg = "A SemLock created in a fork" | ||
| 5434 | + with self.assertRaisesRegex(RuntimeError, err_msg): | ||
| 5435 | + p.start() | ||
| 5436 | + | ||
| 5437 | + # non-fork-based locks can be used with all other start methods | ||
| 5438 | + for queue_method in ["spawn", "forkserver"]: | ||
| 5439 | + for process_method in multiprocessing.get_all_start_methods(): | ||
| 5440 | + queue = multiprocessing.get_context(queue_method).Queue() | ||
| 5441 | + process_ctx = multiprocessing.get_context(process_method) | ||
| 5442 | + p = process_ctx.Process(target=close_queue, args=(queue,)) | ||
| 5443 | + p.start() | ||
| 5444 | + p.join() | ||
| 5445 | + | ||
| 5424 | 5446 | ||
| 5425 | 5447 | @unittest.skipIf(sys.platform == "win32", | |
| 5426 | 5448 | "test semantics don't make sense on Windows") | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -0,0 +1 @@ | |||
| 1 | + Ensure that multiprocessing synchronization objects created in a fork context are not sent to a different process created in a spawn context. This changes a segfault into an actionable RuntimeError in the parent process. | ||
| Back | FazBrowse Home | New Git URL |
0 commit comments