diff options
Diffstat (limited to 'bitbake/lib/bb')
-rw-r--r-- | bitbake/lib/bb/command.py | 26 | ||||
-rw-r--r-- | bitbake/lib/bb/cooker.py | 12 | ||||
-rw-r--r-- | bitbake/lib/bb/server/process.py | 30 |
3 files changed, 44 insertions, 24 deletions
diff --git a/bitbake/lib/bb/command.py b/bitbake/lib/bb/command.py index a29e41afda..9e2cdc5c75 100644 --- a/bitbake/lib/bb/command.py +++ b/bitbake/lib/bb/command.py | |||
@@ -51,13 +51,14 @@ class Command: | |||
51 | """ | 51 | """ |
52 | A queue of asynchronous commands for bitbake | 52 | A queue of asynchronous commands for bitbake |
53 | """ | 53 | """ |
54 | def __init__(self, cooker): | 54 | def __init__(self, cooker, process_server): |
55 | self.cooker = cooker | 55 | self.cooker = cooker |
56 | self.cmds_sync = CommandsSync() | 56 | self.cmds_sync = CommandsSync() |
57 | self.cmds_async = CommandsAsync() | 57 | self.cmds_async = CommandsAsync() |
58 | self.remotedatastores = None | 58 | self.remotedatastores = None |
59 | 59 | ||
60 | # FIXME Add lock for this | 60 | self.process_server = process_server |
61 | # Access with locking using process_server.{get/set/clear}_async_cmd() | ||
61 | self.currentAsyncCommand = None | 62 | self.currentAsyncCommand = None |
62 | 63 | ||
63 | def runCommand(self, commandline, process_server, ro_only=False): | 64 | def runCommand(self, commandline, process_server, ro_only=False): |
@@ -99,18 +100,14 @@ class Command: | |||
99 | return None, traceback.format_exc() | 100 | return None, traceback.format_exc() |
100 | else: | 101 | else: |
101 | return result, None | 102 | return result, None |
102 | if self.currentAsyncCommand is not None: | ||
103 | # Wait for the idle loop to have cleared (30s max) | ||
104 | process_server.wait_for_idle(timeout=30) | ||
105 | if self.currentAsyncCommand is not None: | ||
106 | return None, "Busy (%s in progress)" % self.currentAsyncCommand[0] | ||
107 | if command not in CommandsAsync.__dict__: | 103 | if command not in CommandsAsync.__dict__: |
108 | return None, "No such command" | 104 | return None, "No such command" |
109 | self.currentAsyncCommand = (command, commandline) | 105 | if not process_server.set_async_cmd((command, commandline)): |
110 | self.cooker.idleCallBackRegister(self.runAsyncCommand, None) | 106 | return None, "Busy (%s in progress)" % self.process_server.get_async_cmd()[0] |
107 | self.cooker.idleCallBackRegister(self.runAsyncCommand, process_server) | ||
111 | return True, None | 108 | return True, None |
112 | 109 | ||
113 | def runAsyncCommand(self, _, _2, halt): | 110 | def runAsyncCommand(self, _, process_server, halt): |
114 | try: | 111 | try: |
115 | self.cooker.process_inotify_updates_apply() | 112 | self.cooker.process_inotify_updates_apply() |
116 | if self.cooker.state in (bb.cooker.state.error, bb.cooker.state.shutdown, bb.cooker.state.forceshutdown): | 113 | if self.cooker.state in (bb.cooker.state.error, bb.cooker.state.shutdown, bb.cooker.state.forceshutdown): |
@@ -118,8 +115,9 @@ class Command: | |||
118 | # and then raise BBHandledException triggering an exit | 115 | # and then raise BBHandledException triggering an exit |
119 | self.cooker.updateCache() | 116 | self.cooker.updateCache() |
120 | return bb.server.process.idleFinish("Cooker in error state") | 117 | return bb.server.process.idleFinish("Cooker in error state") |
121 | if self.currentAsyncCommand is not None: | 118 | cmd = process_server.get_async_cmd() |
122 | (command, options) = self.currentAsyncCommand | 119 | if cmd is not None: |
120 | (command, options) = cmd | ||
123 | commandmethod = getattr(CommandsAsync, command) | 121 | commandmethod = getattr(CommandsAsync, command) |
124 | needcache = getattr( commandmethod, "needcache" ) | 122 | needcache = getattr( commandmethod, "needcache" ) |
125 | if needcache and self.cooker.state != bb.cooker.state.running: | 123 | if needcache and self.cooker.state != bb.cooker.state.running: |
@@ -153,7 +151,7 @@ class Command: | |||
153 | else: | 151 | else: |
154 | bb.event.fire(CommandCompleted(), self.cooker.data) | 152 | bb.event.fire(CommandCompleted(), self.cooker.data) |
155 | self.cooker.finishcommand() | 153 | self.cooker.finishcommand() |
156 | self.currentAsyncCommand = None | 154 | self.process_server.clear_async_cmd() |
157 | 155 | ||
158 | def reset(self): | 156 | def reset(self): |
159 | if self.remotedatastores: | 157 | if self.remotedatastores: |
@@ -746,7 +744,7 @@ class CommandsAsync: | |||
746 | """ | 744 | """ |
747 | event = params[0] | 745 | event = params[0] |
748 | bb.event.fire(eval(event), command.cooker.data) | 746 | bb.event.fire(eval(event), command.cooker.data) |
749 | command.currentAsyncCommand = None | 747 | process_server.clear_async_cmd() |
750 | triggerEvent.needcache = False | 748 | triggerEvent.needcache = False |
751 | 749 | ||
752 | def resetCooker(self, command, params): | 750 | def resetCooker(self, command, params): |
diff --git a/bitbake/lib/bb/cooker.py b/bitbake/lib/bb/cooker.py index 13d6e9d847..5a0e675b44 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, waitIdle=None): | 152 | def __init__(self, featureSet=None, server=None): |
153 | self.recipecaches = None | 153 | self.recipecaches = None |
154 | self.eventlog = None | 154 | self.eventlog = None |
155 | self.skiplist = {} | 155 | self.skiplist = {} |
@@ -163,8 +163,12 @@ class BBCooker: | |||
163 | 163 | ||
164 | self.configuration = bb.cookerdata.CookerConfiguration() | 164 | self.configuration = bb.cookerdata.CookerConfiguration() |
165 | 165 | ||
166 | self.idleCallBackRegister = idleCallBackRegister | 166 | self.process_server = server |
167 | self.waitIdle = waitIdle | 167 | self.idleCallBackRegister = None |
168 | self.waitIdle = None | ||
169 | if server: | ||
170 | self.idleCallBackRegister = server.register_idle_function | ||
171 | self.waitIdle = server.wait_for_idle | ||
168 | 172 | ||
169 | bb.debug(1, "BBCooker starting %s" % time.time()) | 173 | bb.debug(1, "BBCooker starting %s" % time.time()) |
170 | sys.stdout.flush() | 174 | sys.stdout.flush() |
@@ -203,7 +207,7 @@ class BBCooker: | |||
203 | except UnsupportedOperation: | 207 | except UnsupportedOperation: |
204 | pass | 208 | pass |
205 | 209 | ||
206 | self.command = bb.command.Command(self) | 210 | self.command = bb.command.Command(self, self.process_server) |
207 | self.state = state.initial | 211 | self.state = state.initial |
208 | 212 | ||
209 | self.parser = None | 213 | self.parser = None |
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 |