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 |