summaryrefslogtreecommitdiffstats
path: root/bitbake/lib/bb
diff options
context:
space:
mode:
authorRichard Purdie <richard.purdie@linuxfoundation.org>2022-12-29 14:56:14 +0000
committerRichard Purdie <richard.purdie@linuxfoundation.org>2022-12-31 17:05:17 +0000
commitc4ecfc4dc5511a23e12ed68eb140a67fd4181127 (patch)
tree46586a8cfdac78f493d58a835b1d6009b8d13c4d /bitbake/lib/bb
parentff2d778f6d33a4e48406f7bbc7fdbc4e95113069 (diff)
downloadpoky-c4ecfc4dc5511a23e12ed68eb140a67fd4181127.tar.gz
bitbake: server/process: Improve idle loop exit code
When idle handlers want to exit, returning "False" isn't very clear and also causes challenges with the ordering of the removing the idle handler and marking that no async command is running. Use a specific class to signal the exit condition allowing clearer code and allowing the async command to be cleared after the handler has been removed, reducing any opportunity for races. (Bitbake rev: 102e8d0d4c5c0dd8c7ba09ad26589deec77e4308) Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
Diffstat (limited to 'bitbake/lib/bb')
-rw-r--r--bitbake/lib/bb/command.py13
-rw-r--r--bitbake/lib/bb/cooker.py13
-rw-r--r--bitbake/lib/bb/server/process.py11
3 files changed, 20 insertions, 17 deletions
diff --git a/bitbake/lib/bb/command.py b/bitbake/lib/bb/command.py
index cbac07f516..732327d84d 100644
--- a/bitbake/lib/bb/command.py
+++ b/bitbake/lib/bb/command.py
@@ -128,22 +128,19 @@ class Command:
128 else: 128 else:
129 return False 129 return False
130 except KeyboardInterrupt as exc: 130 except KeyboardInterrupt as exc:
131 self.finishAsyncCommand("Interrupted") 131 return bb.server.process.idleFinish("Interrupted")
132 return False
133 except SystemExit as exc: 132 except SystemExit as exc:
134 arg = exc.args[0] 133 arg = exc.args[0]
135 if isinstance(arg, str): 134 if isinstance(arg, str):
136 self.finishAsyncCommand(arg) 135 return bb.server.process.idleFinish(arg)
137 else: 136 else:
138 self.finishAsyncCommand("Exited with %s" % arg) 137 return bb.server.process.idleFinish("Exited with %s" % arg)
139 return False
140 except Exception as exc: 138 except Exception as exc:
141 import traceback 139 import traceback
142 if isinstance(exc, bb.BBHandledException): 140 if isinstance(exc, bb.BBHandledException):
143 self.finishAsyncCommand("") 141 return bb.server.process.idleFinish("")
144 else: 142 else:
145 self.finishAsyncCommand(traceback.format_exc()) 143 return bb.server.process.idleFinish(traceback.format_exc())
146 return False
147 144
148 def finishAsyncCommand(self, msg=None, code=None): 145 def finishAsyncCommand(self, msg=None, code=None):
149 if msg or msg == "": 146 if msg or msg == "":
diff --git a/bitbake/lib/bb/cooker.py b/bitbake/lib/bb/cooker.py
index adc232e288..ded9369787 100644
--- a/bitbake/lib/bb/cooker.py
+++ b/bitbake/lib/bb/cooker.py
@@ -1489,23 +1489,21 @@ class BBCooker:
1489 failures += len(exc.args) 1489 failures += len(exc.args)
1490 retval = False 1490 retval = False
1491 except SystemExit as exc: 1491 except SystemExit as exc:
1492 self.command.finishAsyncCommand(str(exc))
1493 if quietlog: 1492 if quietlog:
1494 bb.runqueue.logger.setLevel(rqloglevel) 1493 bb.runqueue.logger.setLevel(rqloglevel)
1495 return False 1494 return bb.server.process.idleFinish(str(exc))
1496 1495
1497 if not retval: 1496 if not retval:
1498 if fireevents: 1497 if fireevents:
1499 bb.event.fire(bb.event.BuildCompleted(len(rq.rqdata.runtaskentries), buildname, item, failures, interrupted), self.databuilder.mcdata[mc]) 1498 bb.event.fire(bb.event.BuildCompleted(len(rq.rqdata.runtaskentries), buildname, item, failures, interrupted), self.databuilder.mcdata[mc])
1500 bb.event.disable_heartbeat() 1499 bb.event.disable_heartbeat()
1501 self.command.finishAsyncCommand(msg)
1502 # We trashed self.recipecaches above 1500 # We trashed self.recipecaches above
1503 self.parsecache_valid = False 1501 self.parsecache_valid = False
1504 self.configuration.limited_deps = False 1502 self.configuration.limited_deps = False
1505 bb.parse.siggen.reset(self.data) 1503 bb.parse.siggen.reset(self.data)
1506 if quietlog: 1504 if quietlog:
1507 bb.runqueue.logger.setLevel(rqloglevel) 1505 bb.runqueue.logger.setLevel(rqloglevel)
1508 return False 1506 return bb.server.process.idleFinish(msg)
1509 if retval is True: 1507 if retval is True:
1510 return True 1508 return True
1511 return retval 1509 return retval
@@ -1535,8 +1533,7 @@ class BBCooker:
1535 failures += len(exc.args) 1533 failures += len(exc.args)
1536 retval = False 1534 retval = False
1537 except SystemExit as exc: 1535 except SystemExit as exc:
1538 self.command.finishAsyncCommand(str(exc)) 1536 return bb.server.process.idleFinish(str(exc))
1539 return False
1540 1537
1541 if not retval: 1538 if not retval:
1542 try: 1539 try:
@@ -1544,8 +1541,8 @@ class BBCooker:
1544 bb.event.fire(bb.event.BuildCompleted(len(rq.rqdata.runtaskentries), buildname, targets, failures, interrupted), self.databuilder.mcdata[mc]) 1541 bb.event.fire(bb.event.BuildCompleted(len(rq.rqdata.runtaskentries), buildname, targets, failures, interrupted), self.databuilder.mcdata[mc])
1545 finally: 1542 finally:
1546 bb.event.disable_heartbeat() 1543 bb.event.disable_heartbeat()
1547 self.command.finishAsyncCommand(msg) 1544 return bb.server.process.idleFinish(msg)
1548 return False 1545
1549 if retval is True: 1546 if retval is True:
1550 return True 1547 return True
1551 return retval 1548 return retval
diff --git a/bitbake/lib/bb/server/process.py b/bitbake/lib/bb/server/process.py
index eba28ad983..5acc105e08 100644
--- a/bitbake/lib/bb/server/process.py
+++ b/bitbake/lib/bb/server/process.py
@@ -71,6 +71,10 @@ def get_lockfile_process_msg(lockfile):
71 return procs.decode("utf-8") 71 return procs.decode("utf-8")
72 return None 72 return None
73 73
74class idleFinish():
75 def __init__(self, msg):
76 self.msg = msg
77
74class ProcessServer(): 78class ProcessServer():
75 profile_filename = "profile.log" 79 profile_filename = "profile.log"
76 profile_processed_filename = "profile.log.processed" 80 profile_processed_filename = "profile.log.processed"
@@ -361,7 +365,12 @@ class ProcessServer():
361 for function, data in list(self._idlefuns.items()): 365 for function, data in list(self._idlefuns.items()):
362 try: 366 try:
363 retval = function(self, data, False) 367 retval = function(self, data, False)
364 if retval is False: 368 if isinstance(retval, idleFinish):
369 serverlog("Removing idle function %s at idleFinish" % str(function))
370 del self._idlefuns[function]
371 self.cooker.command.finishAsyncCommand(retval.msg)
372 nextsleep = None
373 elif retval is False:
365 serverlog("Removing idle function %s" % str(function)) 374 serverlog("Removing idle function %s" % str(function))
366 del self._idlefuns[function] 375 del self._idlefuns[function]
367 nextsleep = None 376 nextsleep = None