1
0
mirror of https://git.yoctoproject.org/poky synced 2026-05-30 12:29:55 +00:00

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>
This commit is contained in:
Richard Purdie
2022-12-29 14:56:14 +00:00
parent ff2d778f6d
commit c4ecfc4dc5
3 changed files with 20 additions and 17 deletions
+5 -8
View File
@@ -128,22 +128,19 @@ class Command:
else: else:
return False return False
except KeyboardInterrupt as exc: except KeyboardInterrupt as exc:
self.finishAsyncCommand("Interrupted") return bb.server.process.idleFinish("Interrupted")
return False
except SystemExit as exc: except SystemExit as exc:
arg = exc.args[0] arg = exc.args[0]
if isinstance(arg, str): if isinstance(arg, str):
self.finishAsyncCommand(arg) return bb.server.process.idleFinish(arg)
else: else:
self.finishAsyncCommand("Exited with %s" % arg) return bb.server.process.idleFinish("Exited with %s" % arg)
return False
except Exception as exc: except Exception as exc:
import traceback import traceback
if isinstance(exc, bb.BBHandledException): if isinstance(exc, bb.BBHandledException):
self.finishAsyncCommand("") return bb.server.process.idleFinish("")
else: else:
self.finishAsyncCommand(traceback.format_exc()) return bb.server.process.idleFinish(traceback.format_exc())
return False
def finishAsyncCommand(self, msg=None, code=None): def finishAsyncCommand(self, msg=None, code=None):
if msg or msg == "": if msg or msg == "":
+5 -8
View File
@@ -1489,23 +1489,21 @@ class BBCooker:
failures += len(exc.args) failures += len(exc.args)
retval = False retval = False
except SystemExit as exc: except SystemExit as exc:
self.command.finishAsyncCommand(str(exc))
if quietlog: if quietlog:
bb.runqueue.logger.setLevel(rqloglevel) bb.runqueue.logger.setLevel(rqloglevel)
return False return bb.server.process.idleFinish(str(exc))
if not retval: if not retval:
if fireevents: if fireevents:
bb.event.fire(bb.event.BuildCompleted(len(rq.rqdata.runtaskentries), buildname, item, failures, interrupted), self.databuilder.mcdata[mc]) bb.event.fire(bb.event.BuildCompleted(len(rq.rqdata.runtaskentries), buildname, item, failures, interrupted), self.databuilder.mcdata[mc])
bb.event.disable_heartbeat() bb.event.disable_heartbeat()
self.command.finishAsyncCommand(msg)
# We trashed self.recipecaches above # We trashed self.recipecaches above
self.parsecache_valid = False self.parsecache_valid = False
self.configuration.limited_deps = False self.configuration.limited_deps = False
bb.parse.siggen.reset(self.data) bb.parse.siggen.reset(self.data)
if quietlog: if quietlog:
bb.runqueue.logger.setLevel(rqloglevel) bb.runqueue.logger.setLevel(rqloglevel)
return False return bb.server.process.idleFinish(msg)
if retval is True: if retval is True:
return True return True
return retval return retval
@@ -1535,8 +1533,7 @@ class BBCooker:
failures += len(exc.args) failures += len(exc.args)
retval = False retval = False
except SystemExit as exc: except SystemExit as exc:
self.command.finishAsyncCommand(str(exc)) return bb.server.process.idleFinish(str(exc))
return False
if not retval: if not retval:
try: try:
@@ -1544,8 +1541,8 @@ class BBCooker:
bb.event.fire(bb.event.BuildCompleted(len(rq.rqdata.runtaskentries), buildname, targets, failures, interrupted), self.databuilder.mcdata[mc]) bb.event.fire(bb.event.BuildCompleted(len(rq.rqdata.runtaskentries), buildname, targets, failures, interrupted), self.databuilder.mcdata[mc])
finally: finally:
bb.event.disable_heartbeat() bb.event.disable_heartbeat()
self.command.finishAsyncCommand(msg) return bb.server.process.idleFinish(msg)
return False
if retval is True: if retval is True:
return True return True
return retval return retval
+10 -1
View File
@@ -71,6 +71,10 @@ def get_lockfile_process_msg(lockfile):
return procs.decode("utf-8") return procs.decode("utf-8")
return None return None
class idleFinish():
def __init__(self, msg):
self.msg = msg
class ProcessServer(): class ProcessServer():
profile_filename = "profile.log" profile_filename = "profile.log"
profile_processed_filename = "profile.log.processed" profile_processed_filename = "profile.log.processed"
@@ -361,7 +365,12 @@ class ProcessServer():
for function, data in list(self._idlefuns.items()): for function, data in list(self._idlefuns.items()):
try: try:
retval = function(self, data, False) retval = function(self, data, False)
if retval is False: if isinstance(retval, idleFinish):
serverlog("Removing idle function %s at idleFinish" % str(function))
del self._idlefuns[function]
self.cooker.command.finishAsyncCommand(retval.msg)
nextsleep = None
elif retval is False:
serverlog("Removing idle function %s" % str(function)) serverlog("Removing idle function %s" % str(function))
del self._idlefuns[function] del self._idlefuns[function]
nextsleep = None nextsleep = None