summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJoshua Watt <JPEWhacker@gmail.com>2025-08-22 00:40:37 +0200
committerSteve Sakoman <steve@sakoman.com>2025-09-17 15:32:27 -0700
commitec065ce64c1d0155e8566c7dd12911ae0c7a04d0 (patch)
tree6f7ec4787ecf27374c063f426b3a9d91a08d53cc
parent5495d8b6ff75e625e78b94503acbb35d0247709c (diff)
downloadpoky-ec065ce64c1d0155e8566c7dd12911ae0c7a04d0.tar.gz
bitbake: Use a "fork" multiprocessing context
Python 3.14 changes the default multiprocessing context from "fork" to "forkserver"; however bitbake heavily relies on "fork" to efficiently pass data to the child processes. As such, make "fork" context in the bb namespace and use it in place of the normal multiprocessing module. Note that multiprocessing contexts were added in Python 3.4, so this should be safe to use even before Python 3.14 [YOCTO #15858] (Bitbake rev: 0d9d8d0863e82e986c33c08064ce9a99224a06d5) Signed-off-by: Joshua Watt <JPEWhacker@gmail.com> Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org> Signed-off-by: Steve Sakoman <steve@sakoman.com>
-rw-r--r--bitbake/lib/bb/__init__.py28
-rw-r--r--bitbake/lib/bb/asyncrpc/serv.py2
-rw-r--r--bitbake/lib/bb/cooker.py2
-rw-r--r--bitbake/lib/bb/server/process.py2
-rw-r--r--bitbake/lib/bb/tests/support/httpserver.py4
-rw-r--r--bitbake/lib/bb/utils.py4
-rw-r--r--bitbake/lib/hashserv/tests.py2
7 files changed, 35 insertions, 9 deletions
diff --git a/bitbake/lib/bb/__init__.py b/bitbake/lib/bb/__init__.py
index 5668355737..605355e1ad 100644
--- a/bitbake/lib/bb/__init__.py
+++ b/bitbake/lib/bb/__init__.py
@@ -37,6 +37,34 @@ class BBHandledException(Exception):
37import os 37import os
38import logging 38import logging
39from collections import namedtuple 39from collections import namedtuple
40import multiprocessing as mp
41
42# Python 3.14 changes the default multiprocessing context from "fork" to
43# "forkserver". However, bitbake heavily relies on "fork" behavior to
44# efficiently pass data to the child processes. Places that need this should do:
45# from bb import multiprocessing
46# in place of
47# import multiprocessing
48
49class MultiprocessingContext(object):
50 """
51 Multiprocessing proxy object that uses the "fork" context for a property if
52 available, otherwise goes to the main multiprocessing module. This allows
53 it to be a drop-in replacement for the multiprocessing module, but use the
54 fork context
55 """
56 def __init__(self):
57 super().__setattr__("_ctx", mp.get_context("fork"))
58
59 def __getattr__(self, name):
60 if hasattr(self._ctx, name):
61 return getattr(self._ctx, name)
62 return getattr(mp, name)
63
64 def __setattr__(self, name, value):
65 raise AttributeError(f"Unable to set attribute {name}")
66
67multiprocessing = MultiprocessingContext()
40 68
41 69
42class NullHandler(logging.Handler): 70class NullHandler(logging.Handler):
diff --git a/bitbake/lib/bb/asyncrpc/serv.py b/bitbake/lib/bb/asyncrpc/serv.py
index 667217c5c1..acdcaf08ed 100644
--- a/bitbake/lib/bb/asyncrpc/serv.py
+++ b/bitbake/lib/bb/asyncrpc/serv.py
@@ -11,7 +11,7 @@ import os
11import signal 11import signal
12import socket 12import socket
13import sys 13import sys
14import multiprocessing 14from bb import multiprocessing
15import logging 15import logging
16from .connection import StreamConnection, WebsocketConnection 16from .connection import StreamConnection, WebsocketConnection
17from .exceptions import ClientError, ServerError, ConnectionClosedError, InvokeError 17from .exceptions import ClientError, ServerError, ConnectionClosedError, InvokeError
diff --git a/bitbake/lib/bb/cooker.py b/bitbake/lib/bb/cooker.py
index 1810bcc604..36659cee26 100644
--- a/bitbake/lib/bb/cooker.py
+++ b/bitbake/lib/bb/cooker.py
@@ -12,7 +12,7 @@ import enum
12import sys, os, glob, os.path, re, time 12import sys, os, glob, os.path, re, time
13import itertools 13import itertools
14import logging 14import logging
15import multiprocessing 15from bb import multiprocessing
16import threading 16import threading
17from io import StringIO, UnsupportedOperation 17from io import StringIO, UnsupportedOperation
18from contextlib import closing 18from contextlib import closing
diff --git a/bitbake/lib/bb/server/process.py b/bitbake/lib/bb/server/process.py
index 4b35be62cd..f74b3f1bf2 100644
--- a/bitbake/lib/bb/server/process.py
+++ b/bitbake/lib/bb/server/process.py
@@ -13,7 +13,7 @@
13import bb 13import bb
14import bb.event 14import bb.event
15import logging 15import logging
16import multiprocessing 16from bb import multiprocessing
17import threading 17import threading
18import array 18import array
19import os 19import os
diff --git a/bitbake/lib/bb/tests/support/httpserver.py b/bitbake/lib/bb/tests/support/httpserver.py
index 78f7660053..03327e923b 100644
--- a/bitbake/lib/bb/tests/support/httpserver.py
+++ b/bitbake/lib/bb/tests/support/httpserver.py
@@ -3,7 +3,7 @@
3# 3#
4 4
5import http.server 5import http.server
6import multiprocessing 6from bb import multiprocessing
7import os 7import os
8import traceback 8import traceback
9import signal 9import signal
@@ -43,7 +43,7 @@ class HTTPService(object):
43 self.process = multiprocessing.Process(target=self.server.server_start, args=[self.root_dir, self.logger]) 43 self.process = multiprocessing.Process(target=self.server.server_start, args=[self.root_dir, self.logger])
44 44
45 # The signal handler from testimage.bbclass can cause deadlocks here 45 # The signal handler from testimage.bbclass can cause deadlocks here
46 # if the HTTPServer is terminated before it can restore the standard 46 # if the HTTPServer is terminated before it can restore the standard
47 #signal behaviour 47 #signal behaviour
48 orig = signal.getsignal(signal.SIGTERM) 48 orig = signal.getsignal(signal.SIGTERM)
49 signal.signal(signal.SIGTERM, signal.SIG_DFL) 49 signal.signal(signal.SIGTERM, signal.SIG_DFL)
diff --git a/bitbake/lib/bb/utils.py b/bitbake/lib/bb/utils.py
index 0832422683..694e79f552 100644
--- a/bitbake/lib/bb/utils.py
+++ b/bitbake/lib/bb/utils.py
@@ -12,7 +12,7 @@ import sys
12import errno 12import errno
13import logging 13import logging
14import locale 14import locale
15import multiprocessing 15from bb import multiprocessing
16import importlib 16import importlib
17import importlib.machinery 17import importlib.machinery
18import importlib.util 18import importlib.util
@@ -1198,8 +1198,6 @@ def process_profilelog(fn, pout = None):
1198# 1198#
1199def multiprocessingpool(*args, **kwargs): 1199def multiprocessingpool(*args, **kwargs):
1200 1200
1201 import multiprocessing.pool
1202 #import multiprocessing.util
1203 #multiprocessing.util.log_to_stderr(10) 1201 #multiprocessing.util.log_to_stderr(10)
1204 # Deal with a multiprocessing bug where signals to the processes would be delayed until the work 1202 # Deal with a multiprocessing bug where signals to the processes would be delayed until the work
1205 # completes. Putting in a timeout means the signals (like SIGINT/SIGTERM) get processed. 1203 # completes. Putting in a timeout means the signals (like SIGINT/SIGTERM) get processed.
diff --git a/bitbake/lib/hashserv/tests.py b/bitbake/lib/hashserv/tests.py
index da3f8e0884..124d8aa005 100644
--- a/bitbake/lib/hashserv/tests.py
+++ b/bitbake/lib/hashserv/tests.py
@@ -10,7 +10,7 @@ from .server import DEFAULT_ANON_PERMS, ALL_PERMISSIONS
10from bb.asyncrpc import InvokeError 10from bb.asyncrpc import InvokeError
11import hashlib 11import hashlib
12import logging 12import logging
13import multiprocessing 13from bb import multiprocessing
14import os 14import os
15import sys 15import sys
16import tempfile 16import tempfile