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 |
