summaryrefslogtreecommitdiffstats
path: root/bitbake/lib
diff options
context:
space:
mode:
Diffstat (limited to 'bitbake/lib')
-rw-r--r--bitbake/lib/bb/__init__.py28
-rw-r--r--bitbake/lib/bb/asyncrpc/serv.py2
-rw-r--r--bitbake/lib/bb/cooker.py8
-rw-r--r--bitbake/lib/bb/server/process.py2
-rw-r--r--bitbake/lib/bb/siggen.py6
-rw-r--r--bitbake/lib/bb/tests/fetch.py2
-rw-r--r--bitbake/lib/bb/tests/support/httpserver.py4
-rw-r--r--bitbake/lib/bb/utils.py52
-rw-r--r--bitbake/lib/hashserv/tests.py2
9 files changed, 65 insertions, 41 deletions
diff --git a/bitbake/lib/bb/__init__.py b/bitbake/lib/bb/__init__.py
index bf4c54d829..3c98b835c6 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 35e93f7c96..bd1aded8db 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 fe33a4f34c..2eb64ef237 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
@@ -2241,9 +2241,9 @@ class CookerParser(object):
2241 profiles.append(logfile) 2241 profiles.append(logfile)
2242 2242
2243 if profiles: 2243 if profiles:
2244 pout = "profile-parse.log.processed" 2244 fn_out = "profile-parse.log.report"
2245 bb.utils.process_profilelog(profiles, pout = pout) 2245 bb.utils.process_profilelog(profiles, fn_out=fn_out)
2246 print("Processed parsing statistics saved to %s" % (pout)) 2246 print("Processed parsing statistics saved to %s" % (fn_out))
2247 2247
2248 def final_cleanup(self): 2248 def final_cleanup(self):
2249 if self.syncthread: 2249 if self.syncthread:
diff --git a/bitbake/lib/bb/server/process.py b/bitbake/lib/bb/server/process.py
index 7d1b38f78c..d0f73590cc 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/siggen.py b/bitbake/lib/bb/siggen.py
index a6163b55ea..41eb643012 100644
--- a/bitbake/lib/bb/siggen.py
+++ b/bitbake/lib/bb/siggen.py
@@ -708,7 +708,7 @@ class SignatureGeneratorUniHashMixIn(object):
708 try: 708 try:
709 with self.client() as client: 709 with self.client() as client:
710 unihashes = client.get_unihash_batch((self._get_method(tid), self.taskhash[tid]) for tid in query_tids) 710 unihashes = client.get_unihash_batch((self._get_method(tid), self.taskhash[tid]) for tid in query_tids)
711 except (ConnectionError, FileNotFoundError) as e: 711 except (ConnectionError, FileNotFoundError, EOFError) as e:
712 bb.warn('Error contacting Hash Equivalence Server %s: %s' % (self.server, str(e))) 712 bb.warn('Error contacting Hash Equivalence Server %s: %s' % (self.server, str(e)))
713 713
714 for idx, tid in enumerate(query_tids): 714 for idx, tid in enumerate(query_tids):
@@ -817,7 +817,7 @@ class SignatureGeneratorUniHashMixIn(object):
817 d.setVar('BB_UNIHASH', new_unihash) 817 d.setVar('BB_UNIHASH', new_unihash)
818 else: 818 else:
819 hashequiv_logger.debug('Reported task %s as unihash %s to %s' % (taskhash, unihash, self.server)) 819 hashequiv_logger.debug('Reported task %s as unihash %s to %s' % (taskhash, unihash, self.server))
820 except (ConnectionError, FileNotFoundError) as e: 820 except (ConnectionError, FileNotFoundError, EOFError) as e:
821 bb.warn('Error contacting Hash Equivalence Server %s: %s' % (self.server, str(e))) 821 bb.warn('Error contacting Hash Equivalence Server %s: %s' % (self.server, str(e)))
822 finally: 822 finally:
823 if sigfile: 823 if sigfile:
@@ -859,7 +859,7 @@ class SignatureGeneratorUniHashMixIn(object):
859 # TODO: What to do here? 859 # TODO: What to do here?
860 hashequiv_logger.verbose('Task %s unihash reported as unwanted hash %s' % (tid, finalunihash)) 860 hashequiv_logger.verbose('Task %s unihash reported as unwanted hash %s' % (tid, finalunihash))
861 861
862 except (ConnectionError, FileNotFoundError) as e: 862 except (ConnectionError, FileNotFoundError, EOFError) as e:
863 bb.warn('Error contacting Hash Equivalence Server %s: %s' % (self.server, str(e))) 863 bb.warn('Error contacting Hash Equivalence Server %s: %s' % (self.server, str(e)))
864 864
865 return False 865 return False
diff --git a/bitbake/lib/bb/tests/fetch.py b/bitbake/lib/bb/tests/fetch.py
index 077472b8b3..cde1bf3390 100644
--- a/bitbake/lib/bb/tests/fetch.py
+++ b/bitbake/lib/bb/tests/fetch.py
@@ -1465,7 +1465,7 @@ class FetchLatestVersionTest(FetcherTest):
1465 # combination version pattern 1465 # combination version pattern
1466 ("sysprof", "git://git.yoctoproject.org/sysprof.git;protocol=https;branch=master", "cd44ee6644c3641507fb53b8a2a69137f2971219", "", "") 1466 ("sysprof", "git://git.yoctoproject.org/sysprof.git;protocol=https;branch=master", "cd44ee6644c3641507fb53b8a2a69137f2971219", "", "")
1467 : "1.2.0", 1467 : "1.2.0",
1468 ("u-boot-mkimage", "git://source.denx.de/u-boot/u-boot.git;branch=master;protocol=https", "62c175fbb8a0f9a926c88294ea9f7e88eb898f6c", "", "") 1468 ("u-boot-mkimage", "git://git.yoctoproject.org/bbfetchtests-u-boot.git;branch=master;protocol=https", "62c175fbb8a0f9a926c88294ea9f7e88eb898f6c", "", "")
1469 : "2014.01", 1469 : "2014.01",
1470 # version pattern "yyyymmdd" 1470 # version pattern "yyyymmdd"
1471 ("mobile-broadband-provider-info", "git://git.yoctoproject.org/mobile-broadband-provider-info.git;protocol=https;branch=master", "4ed19e11c2975105b71b956440acdb25d46a347d", "", "") 1471 ("mobile-broadband-provider-info", "git://git.yoctoproject.org/mobile-broadband-provider-info.git;protocol=https;branch=master", "4ed19e11c2975105b71b956440acdb25d46a347d", "", "")
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 016036dbce..0cf3b1814c 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
@@ -1441,47 +1441,43 @@ def profile_function(profile, function, output_fn, process=True):
1441 prof.dump_stats(output_fn) 1441 prof.dump_stats(output_fn)
1442 if process: 1442 if process:
1443 process_profilelog(output_fn) 1443 process_profilelog(output_fn)
1444 serverlog("Raw profiling information saved to %s and processed statistics to %s.processed" % (output_fn, output_fn)) 1444 serverlog("Raw profiling information saved to %s and processed statistics to %s.report*" % (output_fn, output_fn))
1445 return ret 1445 return ret
1446 else: 1446 else:
1447 return function() 1447 return function()
1448 1448
1449def process_profilelog(fn, pout = None): 1449def process_profilelog(fn, fn_out = None):
1450 # Either call with a list of filenames and set pout or a filename and optionally pout. 1450 # Either call with a list of filenames and set pout or a filename and optionally pout.
1451 if not pout: 1451 import pstats
1452 pout = fn + '.processed'
1453 1452
1454 with open(pout, 'w') as pout: 1453 if not fn_out:
1455 import pstats 1454 fn_out = fn + '.report'
1455
1456 def pstatopen():
1456 if isinstance(fn, list): 1457 if isinstance(fn, list):
1457 p = pstats.Stats(*fn, stream=pout) 1458 return pstats.Stats(*fn, stream=pout)
1458 else: 1459 return pstats.Stats(fn, stream=pout)
1459 p = pstats.Stats(fn, stream=pout) 1460
1461 with open(fn_out + '.time', 'w') as pout:
1462 p = pstatopen()
1460 p.sort_stats('time') 1463 p.sort_stats('time')
1461 p.print_stats() 1464 p.print_stats()
1465
1466 with open(fn_out + '.time-callers', 'w') as pout:
1467 p = pstatopen()
1468 p.sort_stats('time')
1462 p.print_callers() 1469 p.print_callers()
1470
1471 with open(fn_out + '.cumulative', 'w') as pout:
1472 p = pstatopen()
1463 p.sort_stats('cumulative') 1473 p.sort_stats('cumulative')
1464 p.print_stats() 1474 p.print_stats()
1465 1475
1466 pout.flush() 1476 with open(fn_out + '.cumulative-callers', 'w') as pout:
1477 p = pstatopen()
1478 p.sort_stats('cumulative')
1479 p.print_callers()
1467 1480
1468#
1469# Was present to work around multiprocessing pool bugs in python < 2.7.3
1470#
1471def multiprocessingpool(*args, **kwargs):
1472
1473 import multiprocessing.pool
1474 #import multiprocessing.util
1475 #multiprocessing.util.log_to_stderr(10)
1476 # Deal with a multiprocessing bug where signals to the processes would be delayed until the work
1477 # completes. Putting in a timeout means the signals (like SIGINT/SIGTERM) get processed.
1478 def wrapper(func):
1479 def wrap(self, timeout=None):
1480 return func(self, timeout=timeout if timeout is not None else 1e100)
1481 return wrap
1482 multiprocessing.pool.IMapIterator.next = wrapper(multiprocessing.pool.IMapIterator.next)
1483
1484 return multiprocessing.Pool(*args, **kwargs)
1485 1481
1486def exec_flat_python_func(func, *args, **kwargs): 1482def exec_flat_python_func(func, *args, **kwargs):
1487 """Execute a flat python function (defined with ``def funcname(args): ...``) 1483 """Execute a flat python function (defined with ``def funcname(args): ...``)
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