diff options
author | Richard Purdie <richard.purdie@linuxfoundation.org> | 2022-12-30 22:13:45 +0000 |
---|---|---|
committer | Richard Purdie <richard.purdie@linuxfoundation.org> | 2022-12-31 17:05:17 +0000 |
commit | 4c57c6eeecc43d0479380144f3073e61a8b43375 (patch) | |
tree | 75988728828f7c8528d89815ed1f48353f25d40a /bitbake/lib/bb/cooker.py | |
parent | 3cc9aed5a59d7b72b98ef40727102c98b031f911 (diff) | |
download | poky-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.py | 29 |
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() |