From: Shrey Naithani Date: Wed, 11 Mar 2026 12:08:48 +0000 (+0530) Subject: gh-145587: fix busy loop in multiprocessing.connection.wait on Windows (GH-145597) X-Git-Tag: v3.15.0a8~359 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=5d6e8dd683b25348bfe45f6321f9734868199a23;p=thirdparty%2FPython%2Fcpython.git gh-145587: fix busy loop in multiprocessing.connection.wait on Windows (GH-145597) Ensure wait() blocks for the specified timeout when object_list is empty, preventing 100% CPU usage. This aligns the Windows behavior with the Unix implementation. Co-authored-by: AN Long --- diff --git a/Lib/multiprocessing/connection.py b/Lib/multiprocessing/connection.py index 41b36066c62f..9ce996c9ccd2 100644 --- a/Lib/multiprocessing/connection.py +++ b/Lib/multiprocessing/connection.py @@ -1085,14 +1085,22 @@ if sys.platform == 'win32': Returns list of those objects in object_list which are ready/readable. ''' + object_list = list(object_list) + + if not object_list: + if timeout is None: + while True: + time.sleep(1e6) + elif timeout > 0: + time.sleep(timeout) + return [] + if timeout is None: timeout = INFINITE elif timeout < 0: timeout = 0 else: timeout = int(timeout * 1000 + 0.5) - - object_list = list(object_list) waithandle_to_obj = {} ov_list = [] ready_objects = set() diff --git a/Lib/test/_test_multiprocessing.py b/Lib/test/_test_multiprocessing.py index cc07062eee6f..d67fd13fa33b 100644 --- a/Lib/test/_test_multiprocessing.py +++ b/Lib/test/_test_multiprocessing.py @@ -3890,6 +3890,19 @@ class _TestConnection(BaseTestCase): self.assertRaises(OSError, a.recv) self.assertRaises(OSError, b.recv) + @warnings_helper.ignore_fork_in_thread_deprecation_warnings() + def test_wait_empty(self): + if self.TYPE != 'processes': + self.skipTest('test not appropriate for {}'.format(self.TYPE)) + # gh-145587: wait() with empty list should respect timeout + timeout = 0.5 + start = time.monotonic() + res = self.connection.wait([], timeout=timeout) + duration = time.monotonic() - start + + self.assertEqual(res, []) + self.assertGreaterEqual(duration, timeout - 0.1) + class _TestListener(BaseTestCase): ALLOWED_TYPES = ('processes',) diff --git a/Misc/NEWS.d/next/Library/2026-03-07-14-34-39.gh-issue-145587.flFQ5-.rst b/Misc/NEWS.d/next/Library/2026-03-07-14-34-39.gh-issue-145587.flFQ5-.rst new file mode 100644 index 000000000000..c17d01f36b8c --- /dev/null +++ b/Misc/NEWS.d/next/Library/2026-03-07-14-34-39.gh-issue-145587.flFQ5-.rst @@ -0,0 +1 @@ +Resolved a performance regression in ``multiprocessing.connection.wait`` on Windows that caused infinite busy loops when called with no objects. The function now properly yields control to the OS to conserve CPU resources. Patch By Shrey Naithani