diff options
| -rw-r--r-- | bitbake/lib/bb/cooker.py | 4 | ||||
| -rw-r--r-- | bitbake/lib/bb/event.py | 11 | ||||
| -rw-r--r-- | bitbake/lib/bb/runqueue.py | 15 |
3 files changed, 30 insertions, 0 deletions
diff --git a/bitbake/lib/bb/cooker.py b/bitbake/lib/bb/cooker.py index b673fe10ee..c631ec7e6d 100644 --- a/bitbake/lib/bb/cooker.py +++ b/bitbake/lib/bb/cooker.py | |||
| @@ -345,6 +345,7 @@ class BBCooker: | |||
| 345 | elif signum == signal.SIGHUP: | 345 | elif signum == signal.SIGHUP: |
| 346 | bb.warn("Cooker received SIGHUP, shutting down...") | 346 | bb.warn("Cooker received SIGHUP, shutting down...") |
| 347 | self.state = state.forceshutdown | 347 | self.state = state.forceshutdown |
| 348 | bb.event._should_exit.set() | ||
| 348 | 349 | ||
| 349 | def setFeatures(self, features): | 350 | def setFeatures(self, features): |
| 350 | # we only accept a new feature set if we're in state initial, so we can reset without problems | 351 | # we only accept a new feature set if we're in state initial, so we can reset without problems |
| @@ -1520,6 +1521,7 @@ class BBCooker: | |||
| 1520 | msg = None | 1521 | msg = None |
| 1521 | interrupted = 0 | 1522 | interrupted = 0 |
| 1522 | if halt or self.state == state.forceshutdown: | 1523 | if halt or self.state == state.forceshutdown: |
| 1524 | bb.event._should_exit.set() | ||
| 1523 | rq.finish_runqueue(True) | 1525 | rq.finish_runqueue(True) |
| 1524 | msg = "Forced shutdown" | 1526 | msg = "Forced shutdown" |
| 1525 | interrupted = 2 | 1527 | interrupted = 2 |
| @@ -1760,6 +1762,7 @@ class BBCooker: | |||
| 1760 | self.state = state.forceshutdown | 1762 | self.state = state.forceshutdown |
| 1761 | else: | 1763 | else: |
| 1762 | self.state = state.shutdown | 1764 | self.state = state.shutdown |
| 1765 | bb.event._should_exit.set() | ||
| 1763 | 1766 | ||
| 1764 | if self.parser: | 1767 | if self.parser: |
| 1765 | self.parser.shutdown(clean=False) | 1768 | self.parser.shutdown(clean=False) |
| @@ -1770,6 +1773,7 @@ class BBCooker: | |||
| 1770 | self.parser.shutdown(clean=False) | 1773 | self.parser.shutdown(clean=False) |
| 1771 | self.parser.final_cleanup() | 1774 | self.parser.final_cleanup() |
| 1772 | self.state = state.initial | 1775 | self.state = state.initial |
| 1776 | bb.event._should_exit.clear() | ||
| 1773 | 1777 | ||
| 1774 | def reset(self): | 1778 | def reset(self): |
| 1775 | if hasattr(bb.parse, "siggen"): | 1779 | if hasattr(bb.parse, "siggen"): |
diff --git a/bitbake/lib/bb/event.py b/bitbake/lib/bb/event.py index 8b05f93e2f..37cc630c63 100644 --- a/bitbake/lib/bb/event.py +++ b/bitbake/lib/bb/event.py | |||
| @@ -69,6 +69,7 @@ _eventfilter = None | |||
| 69 | _uiready = False | 69 | _uiready = False |
| 70 | _thread_lock = threading.Lock() | 70 | _thread_lock = threading.Lock() |
| 71 | _heartbeat_enabled = False | 71 | _heartbeat_enabled = False |
| 72 | _should_exit = threading.Event() | ||
| 72 | 73 | ||
| 73 | def enable_threadlock(): | 74 | def enable_threadlock(): |
| 74 | # Always needed now | 75 | # Always needed now |
| @@ -86,6 +87,16 @@ def disable_heartbeat(): | |||
| 86 | global _heartbeat_enabled | 87 | global _heartbeat_enabled |
| 87 | _heartbeat_enabled = False | 88 | _heartbeat_enabled = False |
| 88 | 89 | ||
| 90 | # | ||
| 91 | # In long running code, this function should be called periodically | ||
| 92 | # to check if we should exit due to an interuption (.e.g Ctrl+C from the UI) | ||
| 93 | # | ||
| 94 | def check_for_interrupts(d): | ||
| 95 | global _should_exit | ||
| 96 | if _should_exit.is_set(): | ||
| 97 | bb.warn("Exiting due to interrupt.") | ||
| 98 | raise bb.BBHandledException() | ||
| 99 | |||
| 89 | def execute_handler(name, handler, event, d): | 100 | def execute_handler(name, handler, event, d): |
| 90 | event.data = d | 101 | event.data = d |
| 91 | try: | 102 | try: |
diff --git a/bitbake/lib/bb/runqueue.py b/bitbake/lib/bb/runqueue.py index e5bd9311f2..e629ab7e7b 100644 --- a/bitbake/lib/bb/runqueue.py +++ b/bitbake/lib/bb/runqueue.py | |||
| @@ -655,6 +655,7 @@ class RunQueueData: | |||
| 655 | 655 | ||
| 656 | self.init_progress_reporter.start() | 656 | self.init_progress_reporter.start() |
| 657 | self.init_progress_reporter.next_stage() | 657 | self.init_progress_reporter.next_stage() |
| 658 | bb.event.check_for_interrupts(self.cooker.data) | ||
| 658 | 659 | ||
| 659 | # Step A - Work out a list of tasks to run | 660 | # Step A - Work out a list of tasks to run |
| 660 | # | 661 | # |
| @@ -803,6 +804,7 @@ class RunQueueData: | |||
| 803 | #self.dump_data() | 804 | #self.dump_data() |
| 804 | 805 | ||
| 805 | self.init_progress_reporter.next_stage() | 806 | self.init_progress_reporter.next_stage() |
| 807 | bb.event.check_for_interrupts(self.cooker.data) | ||
| 806 | 808 | ||
| 807 | # Resolve recursive 'recrdeptask' dependencies (Part B) | 809 | # Resolve recursive 'recrdeptask' dependencies (Part B) |
| 808 | # | 810 | # |
| @@ -899,6 +901,7 @@ class RunQueueData: | |||
| 899 | self.runtaskentries[tid].depends.difference_update(recursivetasksselfref) | 901 | self.runtaskentries[tid].depends.difference_update(recursivetasksselfref) |
| 900 | 902 | ||
| 901 | self.init_progress_reporter.next_stage() | 903 | self.init_progress_reporter.next_stage() |
| 904 | bb.event.check_for_interrupts(self.cooker.data) | ||
| 902 | 905 | ||
| 903 | #self.dump_data() | 906 | #self.dump_data() |
| 904 | 907 | ||
| @@ -980,6 +983,7 @@ class RunQueueData: | |||
| 980 | mark_active(tid, 1) | 983 | mark_active(tid, 1) |
| 981 | 984 | ||
| 982 | self.init_progress_reporter.next_stage() | 985 | self.init_progress_reporter.next_stage() |
| 986 | bb.event.check_for_interrupts(self.cooker.data) | ||
| 983 | 987 | ||
| 984 | # Step C - Prune all inactive tasks | 988 | # Step C - Prune all inactive tasks |
| 985 | # | 989 | # |
| @@ -1019,6 +1023,7 @@ class RunQueueData: | |||
| 1019 | bb.msg.fatal("RunQueue", "Could not find any tasks with the tasknames %s to run within the recipes of the taskgraphs of the targets %s" % (str(self.cooker.configuration.runall), str(self.targets))) | 1023 | bb.msg.fatal("RunQueue", "Could not find any tasks with the tasknames %s to run within the recipes of the taskgraphs of the targets %s" % (str(self.cooker.configuration.runall), str(self.targets))) |
| 1020 | 1024 | ||
| 1021 | self.init_progress_reporter.next_stage() | 1025 | self.init_progress_reporter.next_stage() |
| 1026 | bb.event.check_for_interrupts(self.cooker.data) | ||
| 1022 | 1027 | ||
| 1023 | # Handle runonly | 1028 | # Handle runonly |
| 1024 | if self.cooker.configuration.runonly: | 1029 | if self.cooker.configuration.runonly: |
| @@ -1059,6 +1064,7 @@ class RunQueueData: | |||
| 1059 | logger.verbose("Assign Weightings") | 1064 | logger.verbose("Assign Weightings") |
| 1060 | 1065 | ||
| 1061 | self.init_progress_reporter.next_stage() | 1066 | self.init_progress_reporter.next_stage() |
| 1067 | bb.event.check_for_interrupts(self.cooker.data) | ||
| 1062 | 1068 | ||
| 1063 | # Generate a list of reverse dependencies to ease future calculations | 1069 | # Generate a list of reverse dependencies to ease future calculations |
| 1064 | for tid in self.runtaskentries: | 1070 | for tid in self.runtaskentries: |
| @@ -1066,6 +1072,7 @@ class RunQueueData: | |||
| 1066 | self.runtaskentries[dep].revdeps.add(tid) | 1072 | self.runtaskentries[dep].revdeps.add(tid) |
| 1067 | 1073 | ||
| 1068 | self.init_progress_reporter.next_stage() | 1074 | self.init_progress_reporter.next_stage() |
| 1075 | bb.event.check_for_interrupts(self.cooker.data) | ||
| 1069 | 1076 | ||
| 1070 | # Identify tasks at the end of dependency chains | 1077 | # Identify tasks at the end of dependency chains |
| 1071 | # Error on circular dependency loops (length two) | 1078 | # Error on circular dependency loops (length two) |
| @@ -1082,12 +1089,14 @@ class RunQueueData: | |||
| 1082 | logger.verbose("Compute totals (have %s endpoint(s))", len(endpoints)) | 1089 | logger.verbose("Compute totals (have %s endpoint(s))", len(endpoints)) |
| 1083 | 1090 | ||
| 1084 | self.init_progress_reporter.next_stage() | 1091 | self.init_progress_reporter.next_stage() |
| 1092 | bb.event.check_for_interrupts(self.cooker.data) | ||
| 1085 | 1093 | ||
| 1086 | # Calculate task weights | 1094 | # Calculate task weights |
| 1087 | # Check of higher length circular dependencies | 1095 | # Check of higher length circular dependencies |
| 1088 | self.runq_weight = self.calculate_task_weights(endpoints) | 1096 | self.runq_weight = self.calculate_task_weights(endpoints) |
| 1089 | 1097 | ||
| 1090 | self.init_progress_reporter.next_stage() | 1098 | self.init_progress_reporter.next_stage() |
| 1099 | bb.event.check_for_interrupts(self.cooker.data) | ||
| 1091 | 1100 | ||
| 1092 | # Sanity Check - Check for multiple tasks building the same provider | 1101 | # Sanity Check - Check for multiple tasks building the same provider |
| 1093 | for mc in self.dataCaches: | 1102 | for mc in self.dataCaches: |
| @@ -1188,6 +1197,7 @@ class RunQueueData: | |||
| 1188 | 1197 | ||
| 1189 | self.init_progress_reporter.next_stage() | 1198 | self.init_progress_reporter.next_stage() |
| 1190 | self.init_progress_reporter.next_stage() | 1199 | self.init_progress_reporter.next_stage() |
| 1200 | bb.event.check_for_interrupts(self.cooker.data) | ||
| 1191 | 1201 | ||
| 1192 | # Iterate over the task list looking for tasks with a 'setscene' function | 1202 | # Iterate over the task list looking for tasks with a 'setscene' function |
| 1193 | self.runq_setscene_tids = set() | 1203 | self.runq_setscene_tids = set() |
| @@ -1200,6 +1210,7 @@ class RunQueueData: | |||
| 1200 | self.runq_setscene_tids.add(tid) | 1210 | self.runq_setscene_tids.add(tid) |
| 1201 | 1211 | ||
| 1202 | self.init_progress_reporter.next_stage() | 1212 | self.init_progress_reporter.next_stage() |
| 1213 | bb.event.check_for_interrupts(self.cooker.data) | ||
| 1203 | 1214 | ||
| 1204 | # Invalidate task if force mode active | 1215 | # Invalidate task if force mode active |
| 1205 | if self.cooker.configuration.force: | 1216 | if self.cooker.configuration.force: |
| @@ -1216,6 +1227,7 @@ class RunQueueData: | |||
| 1216 | invalidate_task(fn + ":" + st, True) | 1227 | invalidate_task(fn + ":" + st, True) |
| 1217 | 1228 | ||
| 1218 | self.init_progress_reporter.next_stage() | 1229 | self.init_progress_reporter.next_stage() |
| 1230 | bb.event.check_for_interrupts(self.cooker.data) | ||
| 1219 | 1231 | ||
| 1220 | # Create and print to the logs a virtual/xxxx -> PN (fn) table | 1232 | # Create and print to the logs a virtual/xxxx -> PN (fn) table |
| 1221 | for mc in taskData: | 1233 | for mc in taskData: |
| @@ -1228,6 +1240,7 @@ class RunQueueData: | |||
| 1228 | bb.parse.siggen.tasks_resolved(virtmap, virtpnmap, self.dataCaches[mc]) | 1240 | bb.parse.siggen.tasks_resolved(virtmap, virtpnmap, self.dataCaches[mc]) |
| 1229 | 1241 | ||
| 1230 | self.init_progress_reporter.next_stage() | 1242 | self.init_progress_reporter.next_stage() |
| 1243 | bb.event.check_for_interrupts(self.cooker.data) | ||
| 1231 | 1244 | ||
| 1232 | bb.parse.siggen.set_setscene_tasks(self.runq_setscene_tids) | 1245 | bb.parse.siggen.set_setscene_tasks(self.runq_setscene_tids) |
| 1233 | 1246 | ||
| @@ -1240,6 +1253,7 @@ class RunQueueData: | |||
| 1240 | dealtwith.add(tid) | 1253 | dealtwith.add(tid) |
| 1241 | todeal.remove(tid) | 1254 | todeal.remove(tid) |
| 1242 | self.prepare_task_hash(tid) | 1255 | self.prepare_task_hash(tid) |
| 1256 | bb.event.check_for_interrupts(self.cooker.data) | ||
| 1243 | 1257 | ||
| 1244 | bb.parse.siggen.writeout_file_checksum_cache() | 1258 | bb.parse.siggen.writeout_file_checksum_cache() |
| 1245 | 1259 | ||
| @@ -1483,6 +1497,7 @@ class RunQueue: | |||
| 1483 | """ | 1497 | """ |
| 1484 | 1498 | ||
| 1485 | retval = True | 1499 | retval = True |
| 1500 | bb.event.check_for_interrupts(self.cooker.data) | ||
| 1486 | 1501 | ||
| 1487 | if self.state is runQueuePrepare: | 1502 | if self.state is runQueuePrepare: |
| 1488 | # NOTE: if you add, remove or significantly refactor the stages of this | 1503 | # NOTE: if you add, remove or significantly refactor the stages of this |
