Files
poky/bitbake/lib/bb/tests/support/httpserver.py
Joshua Watt f00c4968ff 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: 15d7448e04aa78c827d2cef9eb1a62bd6e0dd119)

Signed-off-by: Joshua Watt <JPEWhacker@gmail.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
Signed-off-by: Martin Jansa <martin.jansa@gmail.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
Signed-off-by: Steve Sakoman <steve@sakoman.com>
2025-09-17 15:36:44 -07:00

66 lines
2.0 KiB
Python

#
# SPDX-License-Identifier: MIT
#
import http.server
from bb import multiprocessing
import os
import traceback
import signal
import logging
from socketserver import ThreadingMixIn
class HTTPServer(ThreadingMixIn, http.server.HTTPServer):
def server_start(self, root_dir, logger):
os.chdir(root_dir)
self.serve_forever()
class HTTPRequestHandler(http.server.SimpleHTTPRequestHandler):
def log_message(self, format_str, *args):
pass
class HTTPService(object):
def __init__(self, root_dir, host='', port=0, logger=None):
self.root_dir = root_dir
self.host = host
self.port = port
if not logger:
logger = logging.getLogger()
self.logger = logger
def start(self):
print(self.root_dir)
if not os.path.exists(self.root_dir):
self.logger.info("Not starting HTTPService for directory %s which doesn't exist" % (self.root_dir))
return
self.server = HTTPServer((self.host, self.port), HTTPRequestHandler)
if self.port == 0:
self.port = self.server.server_port
self.process = multiprocessing.Process(target=self.server.server_start, args=[self.root_dir, self.logger])
# The signal handler from testimage.bbclass can cause deadlocks here
# if the HTTPServer is terminated before it can restore the standard
#signal behaviour
orig = signal.getsignal(signal.SIGTERM)
signal.signal(signal.SIGTERM, signal.SIG_DFL)
self.process.start()
signal.signal(signal.SIGTERM, orig)
if self.logger:
self.logger.info("Started HTTPService on %s:%s" % (self.host, self.port))
def stop(self):
if hasattr(self, "server"):
self.server.server_close()
if hasattr(self, "process"):
self.process.terminate()
self.process.join()
if self.logger:
self.logger.info("Stopped HTTPService on %s:%s" % (self.host, self.port))