summaryrefslogtreecommitdiffstats
path: root/bitbake/lib/bb/cooker.py
diff options
context:
space:
mode:
authorRichard Purdie <richard.purdie@linuxfoundation.org>2022-12-30 22:13:45 +0000
committerRichard Purdie <richard.purdie@linuxfoundation.org>2022-12-31 17:05:17 +0000
commit4c57c6eeecc43d0479380144f3073e61a8b43375 (patch)
tree75988728828f7c8528d89815ed1f48353f25d40a /bitbake/lib/bb/cooker.py
parent3cc9aed5a59d7b72b98ef40727102c98b031f911 (diff)
downloadpoky-4c57c6eeecc43d0479380144f3073e61a8b43375.tar.gz
bitbake: server/process: Run idle commands in a separate idle thread
When bitbake is off running heavier "idle" commands, it doesn't service it's command socket which means stopping/interrupting it is hard. It also means we can't "ping" from the UI to know if it is still alive. For those reasons, split idle command execution into it's own thread. The commands are generally already self containted so this is easier than expected. We do have to be careful to only handle inotify poll() from a single thread at a time. It also means we always have to use a thread lock when sending events since both the idle thread and the command thread may generate log messages (and hence events). The patch depends on previous fixes to the builtins locking in event.py and the heartbeat enable/disable changes as well as other locking additions. We use a condition to signal from the idle thread when other sections of code can continue, thanks to Joshua Watt for the review and tweaks squashed into this patch. We do have some sync points where we need to ensure any currently executing commands have finished before we can start a new async command for example. (Bitbake rev: 67dd9a5e84811df8869a82da6a37a41ee8fe94e2) Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
Diffstat (limited to 'bitbake/lib/bb/cooker.py')
-rw-r--r--bitbake/lib/bb/cooker.py29
1 files changed, 21 insertions, 8 deletions
diff --git a/bitbake/lib/bb/cooker.py b/bitbake/lib/bb/cooker.py
index ded9369787..a5a635858c 100644
--- a/bitbake/lib/bb/cooker.py
+++ b/bitbake/lib/bb/cooker.py
@@ -149,7 +149,7 @@ class BBCooker:
149 Manages one bitbake build run 149 Manages one bitbake build run
150 """ 150 """
151 151
152 def __init__(self, featureSet=None, idleCallBackRegister=None): 152 def __init__(self, featureSet=None, idleCallBackRegister=None, waitIdle=None):
153 self.recipecaches = None 153 self.recipecaches = None
154 self.eventlog = None 154 self.eventlog = None
155 self.skiplist = {} 155 self.skiplist = {}
@@ -164,6 +164,7 @@ class BBCooker:
164 self.configuration = bb.cookerdata.CookerConfiguration() 164 self.configuration = bb.cookerdata.CookerConfiguration()
165 165
166 self.idleCallBackRegister = idleCallBackRegister 166 self.idleCallBackRegister = idleCallBackRegister
167 self.waitIdle = waitIdle
167 168
168 bb.debug(1, "BBCooker starting %s" % time.time()) 169 bb.debug(1, "BBCooker starting %s" % time.time())
169 sys.stdout.flush() 170 sys.stdout.flush()
@@ -220,6 +221,8 @@ class BBCooker:
220 bb.debug(1, "BBCooker startup complete %s" % time.time()) 221 bb.debug(1, "BBCooker startup complete %s" % time.time())
221 sys.stdout.flush() 222 sys.stdout.flush()
222 223
224 self.inotify_threadlock = threading.Lock()
225
223 def init_configdata(self): 226 def init_configdata(self):
224 if not hasattr(self, "data"): 227 if not hasattr(self, "data"):
225 self.initConfigurationData() 228 self.initConfigurationData()
@@ -248,11 +251,18 @@ class BBCooker:
248 self.notifier = pyinotify.Notifier(self.watcher, self.notifications) 251 self.notifier = pyinotify.Notifier(self.watcher, self.notifications)
249 252
250 def process_inotify_updates(self): 253 def process_inotify_updates(self):
251 for n in [self.confignotifier, self.notifier]: 254 with self.inotify_threadlock:
252 if n and n.check_events(timeout=0): 255 for n in [self.confignotifier, self.notifier]:
253 # read notified events and enqueue them 256 if n and n.check_events(timeout=0):
254 n.read_events() 257 # read notified events and enqueue them
255 n.process_events() 258 n.read_events()
259
260 def process_inotify_updates_apply(self):
261 with self.inotify_threadlock:
262 for n in [self.confignotifier, self.notifier]:
263 if n and n.check_events(timeout=0):
264 n.read_events()
265 n.process_events()
256 266
257 def config_notifications(self, event): 267 def config_notifications(self, event):
258 if event.maskname == "IN_Q_OVERFLOW": 268 if event.maskname == "IN_Q_OVERFLOW":
@@ -1744,7 +1754,7 @@ class BBCooker:
1744 return 1754 return
1745 1755
1746 def post_serve(self): 1756 def post_serve(self):
1747 self.shutdown(force=True) 1757 self.shutdown(force=True, idle=False)
1748 prserv.serv.auto_shutdown() 1758 prserv.serv.auto_shutdown()
1749 if hasattr(bb.parse, "siggen"): 1759 if hasattr(bb.parse, "siggen"):
1750 bb.parse.siggen.exit() 1760 bb.parse.siggen.exit()
@@ -1754,12 +1764,15 @@ class BBCooker:
1754 if hasattr(self, "data"): 1764 if hasattr(self, "data"):
1755 bb.event.fire(CookerExit(), self.data) 1765 bb.event.fire(CookerExit(), self.data)
1756 1766
1757 def shutdown(self, force = False): 1767 def shutdown(self, force=False, idle=True):
1758 if force: 1768 if force:
1759 self.state = state.forceshutdown 1769 self.state = state.forceshutdown
1760 else: 1770 else:
1761 self.state = state.shutdown 1771 self.state = state.shutdown
1762 1772
1773 if idle:
1774 self.waitIdle(30)
1775
1763 if self.parser: 1776 if self.parser:
1764 self.parser.shutdown(clean=not force) 1777 self.parser.shutdown(clean=not force)
1765 self.parser.final_cleanup() 1778 self.parser.final_cleanup()