summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--bitbake/lib/bb/cooker.py4
-rw-r--r--bitbake/lib/bb/event.py11
-rw-r--r--bitbake/lib/bb/runqueue.py15
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
73def enable_threadlock(): 74def 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#
94def 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
89def execute_handler(name, handler, event, d): 100def 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