From 3f900977104afa06f3c0d525459639598086c131 Mon Sep 17 00:00:00 2001 From: Tim Felgentreff Date: Wed, 18 Mar 2026 15:34:08 +0100 Subject: [PATCH 1/2] [GR-74148] Relax multiprocessing wait timeout upper bound --- .../src/tests/test_multiprocessing_graalpy.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/graalpython/com.oracle.graal.python.test/src/tests/test_multiprocessing_graalpy.py b/graalpython/com.oracle.graal.python.test/src/tests/test_multiprocessing_graalpy.py index 0a49071bb5..81a9cb0fac 100644 --- a/graalpython/com.oracle.graal.python.test/src/tests/test_multiprocessing_graalpy.py +++ b/graalpython/com.oracle.graal.python.test/src/tests/test_multiprocessing_graalpy.py @@ -1,4 +1,4 @@ -# Copyright (c) 2020, 2024, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2020, 2026, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # The Universal Permissive License (UPL), Version 1.0 @@ -80,7 +80,9 @@ def test_wait_timeout(): res = wait(fds, timeout) delta = time.monotonic() - start assert not res - assert delta < timeout * 2 + # The GraalPy multiprocessing wait path actively polls fake file descriptors and may + # overshoot under scheduling contention. + assert delta < timeout * 8 assert delta > timeout / 2 From 28ebc3de353b1e011afe3e6efdb9c2eec446021d Mon Sep 17 00:00:00 2001 From: Tim Felgentreff Date: Thu, 19 Mar 2026 11:02:20 +0100 Subject: [PATCH 2/2] Start warning about using the graalpy multiprocessing backend --- .../lib-python/3/multiprocessing/context.py | 24 ++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) diff --git a/graalpython/lib-python/3/multiprocessing/context.py b/graalpython/lib-python/3/multiprocessing/context.py index 3007a6c565..b2e05351a0 100644 --- a/graalpython/lib-python/3/multiprocessing/context.py +++ b/graalpython/lib-python/3/multiprocessing/context.py @@ -23,6 +23,24 @@ class TimeoutError(ProcessError): class AuthenticationError(ProcessError): pass + +# Begin Truffle change +_graalpy_backend_futurewarned = False + + +def _warn_graalpy_backend_futurewarning_once(stacklevel): + import warnings + global _graalpy_backend_futurewarned + if not _graalpy_backend_futurewarned: + warnings.warn( + "The 'graalpy' multiprocessing backend is deprecated and will be removed in a future " + "GraalPy release. Use the 'spawn' start method where available.", + FutureWarning, + stacklevel=stacklevel, + ) + _graalpy_backend_futurewarned = True +# End Truffle change + # # Base type for contexts. Bound methods of an instance of this type are included in __all__ of __init__.py # @@ -215,7 +233,10 @@ def _check_available(self): # Begin Truffle change def _is_graalpy(self): - return isinstance(self.get_context(), GraalPyContext) + is_graalpy = isinstance(self.get_context(), GraalPyContext) + if is_graalpy: + _warn_graalpy_backend_futurewarning_once(stacklevel=3) + return is_graalpy def _get_id(self): if self._is_graalpy(): @@ -321,6 +342,7 @@ class GraalPyProcess(process.BaseProcess): _start_method = 'graalpy' @staticmethod def _Popen(process_obj): + _warn_graalpy_backend_futurewarning_once(stacklevel=3) from multiprocessing.popen_truffleprocess import Popen return Popen(process_obj)