diff options
author | Richard Purdie <richard.purdie@linuxfoundation.org> | 2023-01-09 23:17:56 +0000 |
---|---|---|
committer | Richard Purdie <richard.purdie@linuxfoundation.org> | 2023-01-11 10:58:36 +0000 |
commit | 165e8b563d400bf54c317659a267db85e8c34006 (patch) | |
tree | 7e4d05e7d3440b6f95c029afabf1822d3f7b2733 /bitbake/lib/bb/server/process.py | |
parent | 4e4f040a73ca81f830cf90af05b75e7c06f91d8d (diff) | |
download | poky-165e8b563d400bf54c317659a267db85e8c34006.tar.gz |
bitbake: process/cooker/command: Fix currentAsyncCommand locking/races
currentAsyncCommand currently doesn't have any locking and we have
a conflict in "idle" conditions since the idle functions count needs
to be zero *and* there needs to be no active command.
Move the changes/checks of currentAsyncCommand to within the lock
and then we can add it to the condition for idle, simplifying some
of the code.
(Bitbake rev: b5215887d2f8ea3f28f1ebda721bd5b8f93ec7f3)
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
Diffstat (limited to 'bitbake/lib/bb/server/process.py')
-rw-r--r-- | bitbake/lib/bb/server/process.py | 30 |
1 files changed, 24 insertions, 6 deletions
diff --git a/bitbake/lib/bb/server/process.py b/bitbake/lib/bb/server/process.py index 81e5229c9d..a25f04d148 100644 --- a/bitbake/lib/bb/server/process.py +++ b/bitbake/lib/bb/server/process.py | |||
@@ -154,10 +154,30 @@ class ProcessServer(): | |||
154 | 154 | ||
155 | return ret | 155 | return ret |
156 | 156 | ||
157 | def _idle_check(self): | ||
158 | return len(self._idlefuns) == 0 and self.cooker.command.currentAsyncCommand is None | ||
159 | |||
157 | def wait_for_idle(self, timeout=30): | 160 | def wait_for_idle(self, timeout=30): |
158 | # Wait for the idle loop to have cleared | 161 | # Wait for the idle loop to have cleared |
159 | with self.idle_cond: | 162 | with bb.utils.lock_timeout(self._idlefuncsLock): |
160 | self.idle_cond.wait_for(lambda: len(self._idlefuns) == 0, timeout) | 163 | return self.idle_cond.wait_for(self._idle_check, timeout) is not False |
164 | |||
165 | def set_async_cmd(self, cmd): | ||
166 | with bb.utils.lock_timeout(self._idlefuncsLock): | ||
167 | ret = self.idle_cond.wait_for(self._idle_check, 30) | ||
168 | if ret is False: | ||
169 | return False | ||
170 | self.cooker.command.currentAsyncCommand = cmd | ||
171 | return True | ||
172 | |||
173 | def clear_async_cmd(self): | ||
174 | with bb.utils.lock_timeout(self._idlefuncsLock): | ||
175 | self.cooker.command.currentAsyncCommand = None | ||
176 | self.idle_cond.notify_all() | ||
177 | |||
178 | def get_async_cmd(self): | ||
179 | with bb.utils.lock_timeout(self._idlefuncsLock): | ||
180 | return self.cooker.command.currentAsyncCommand | ||
161 | 181 | ||
162 | def main(self): | 182 | def main(self): |
163 | self.cooker.pre_serve() | 183 | self.cooker.pre_serve() |
@@ -183,11 +203,9 @@ class ProcessServer(): | |||
183 | self.controllersock = False | 203 | self.controllersock = False |
184 | if self.haveui: | 204 | if self.haveui: |
185 | # Wait for the idle loop to have cleared (30s max) | 205 | # Wait for the idle loop to have cleared (30s max) |
186 | self.wait_for_idle(30) | 206 | if not self.wait_for_idle(30): |
187 | if self.cooker.command.currentAsyncCommand is not None: | ||
188 | serverlog("Idle loop didn't finish queued commands after 30s, exiting.") | 207 | serverlog("Idle loop didn't finish queued commands after 30s, exiting.") |
189 | self.quit = True | 208 | self.quit = True |
190 | |||
191 | fds.remove(self.command_channel) | 209 | fds.remove(self.command_channel) |
192 | bb.event.unregister_UIHhandler(self.event_handle, True) | 210 | bb.event.unregister_UIHhandler(self.event_handle, True) |
193 | self.command_channel_reply.writer.close() | 211 | self.command_channel_reply.writer.close() |
@@ -624,7 +642,7 @@ def execServer(lockfd, readypipeinfd, lockname, sockname, server_timeout, xmlrpc | |||
624 | writer = ConnectionWriter(readypipeinfd) | 642 | writer = ConnectionWriter(readypipeinfd) |
625 | try: | 643 | try: |
626 | featureset = [] | 644 | featureset = [] |
627 | cooker = bb.cooker.BBCooker(featureset, server.register_idle_function, server.wait_for_idle) | 645 | cooker = bb.cooker.BBCooker(featureset, server) |
628 | cooker.configuration.profile = profile | 646 | cooker.configuration.profile = profile |
629 | except bb.BBHandledException: | 647 | except bb.BBHandledException: |
630 | return None | 648 | return None |