summaryrefslogtreecommitdiffstats
path: root/bitbake/lib/bb/runqueue.py
diff options
context:
space:
mode:
Diffstat (limited to 'bitbake/lib/bb/runqueue.py')
-rw-r--r--bitbake/lib/bb/runqueue.py72
1 files changed, 46 insertions, 26 deletions
diff --git a/bitbake/lib/bb/runqueue.py b/bitbake/lib/bb/runqueue.py
index 3dde9a9ffb..07821e23de 100644
--- a/bitbake/lib/bb/runqueue.py
+++ b/bitbake/lib/bb/runqueue.py
@@ -1,4 +1,4 @@
1 #!/usr/bin/env python 1#!/usr/bin/env python
2# ex:ts=4:sw=4:sts=4:et 2# ex:ts=4:sw=4:sts=4:et
3# -*- tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*- 3# -*- tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*-
4""" 4"""
@@ -25,9 +25,8 @@ import bb, os, sys
25 25
26class TaskFailure(Exception): 26class TaskFailure(Exception):
27 """Exception raised when a task in a runqueue fails""" 27 """Exception raised when a task in a runqueue fails"""
28 28 def __init__(self, x):
29 def __init__(self, fnid, fn, taskname): 29 self.args = x
30 self.args = fnid, fn, taskname
31 30
32class RunQueue: 31class RunQueue:
33 """ 32 """
@@ -319,21 +318,23 @@ class RunQueue:
319 318
320 failures = 0 319 failures = 0
321 while 1: 320 while 1:
322 try: 321 failed_fnids = self.execute_runqueue_internal(cooker, cfgData, dataCache, taskData)
323 self.execute_runqueue_internal(cooker, cfgData, dataCache, taskData) 322 if len(failed_fnids) == 0:
324 return failures 323 return failures
325 except bb.runqueue.TaskFailure, (fnid, taskData.fn_index[fnid], taskname): 324 if taskData.abort:
326 if taskData.abort: 325 raise bb.runqueue.TaskFailure(failed_fnids)
327 raise 326 for fnid in failed_fnids:
327 #print "Failure: %s %s %s" % (fnid, taskData.fn_index[fnid], self.runq_task[fnid])
328 taskData.fail_fnid(fnid) 328 taskData.fail_fnid(fnid)
329 self.reset_runqueue()
330 self.prepare_runqueue(cfgData, dataCache, taskData, runlist)
331 failures = failures + 1 329 failures = failures + 1
330 self.reset_runqueue()
331 self.prepare_runqueue(cfgData, dataCache, taskData, runlist)
332 332
333 def execute_runqueue_internal(self, cooker, cfgData, dataCache, taskData): 333 def execute_runqueue_internal(self, cooker, cfgData, dataCache, taskData):
334 """ 334 """
335 Run the tasks in a queue prepared by prepare_runqueue 335 Run the tasks in a queue prepared by prepare_runqueue
336 """ 336 """
337 import signal
337 338
338 bb.msg.note(1, bb.msg.domain.RunQueue, "Executing runqueue") 339 bb.msg.note(1, bb.msg.domain.RunQueue, "Executing runqueue")
339 340
@@ -342,11 +343,15 @@ class RunQueue:
342 runq_complete = [] 343 runq_complete = []
343 active_builds = 0 344 active_builds = 0
344 build_pids = {} 345 build_pids = {}
346 failed_fnids = []
345 347
346 if len(self.runq_fnid) == 0: 348 if len(self.runq_fnid) == 0:
347 # nothing to do 349 # nothing to do
348 return 350 return
349 351
352 def sigint_handler(signum, frame):
353 raise KeyboardInterrupt
354
350 def get_next_task(data): 355 def get_next_task(data):
351 """ 356 """
352 Return the id of the highest priority task that is buildable 357 Return the id of the highest priority task that is buildable
@@ -414,6 +419,11 @@ class RunQueue:
414 except OSError, e: 419 except OSError, e:
415 bb.msg.fatal(bb.msg.domain.RunQueue, "fork failed: %d (%s)" % (e.errno, e.strerror)) 420 bb.msg.fatal(bb.msg.domain.RunQueue, "fork failed: %d (%s)" % (e.errno, e.strerror))
416 if pid == 0: 421 if pid == 0:
422 # Bypass finally below
423 active_builds = 0
424 # Stop Ctrl+C being sent to children
425 signal.signal(signal.SIGINT, signal.SIG_IGN)
426 sys.stdin = open('/dev/null', 'r')
417 cooker.configuration.cmd = taskname[3:] 427 cooker.configuration.cmd = taskname[3:]
418 try: 428 try:
419 cooker.tryBuild(fn, False) 429 cooker.tryBuild(fn, False)
@@ -434,26 +444,36 @@ class RunQueue:
434 active_builds = active_builds - 1 444 active_builds = active_builds - 1
435 task = build_pids[result[0]] 445 task = build_pids[result[0]]
436 if result[1] != 0: 446 if result[1] != 0:
447 del build_pids[result[0]]
437 bb.msg.error(bb.msg.domain.RunQueue, "Task %s (%s) failed" % (task, self.get_user_idstring(task, taskData))) 448 bb.msg.error(bb.msg.domain.RunQueue, "Task %s (%s) failed" % (task, self.get_user_idstring(task, taskData)))
438 raise bb.runqueue.TaskFailure(self.runq_fnid[task], taskData.fn_index[self.runq_fnid[task]], self.runq_task[task]) 449 failed_fnids.append(self.runq_fnid[task])
450 break
439 task_complete(self, task) 451 task_complete(self, task)
440 del build_pids[result[0]] 452 del build_pids[result[0]]
441 continue 453 continue
442 break 454 break
443 except SystemExit: 455 finally:
444 raise 456 try:
445 except: 457 while active_builds > 0:
446 bb.msg.error(bb.msg.domain.RunQueue, "Exception received") 458 bb.msg.note(1, bb.msg.domain.RunQueue, "Waiting for %s active tasks to finish" % active_builds)
447 while active_builds > 0: 459 tasknum = 1
448 bb.msg.note(1, bb.msg.domain.RunQueue, "Waiting for %s active tasks to finish" % active_builds) 460 for k, v in build_pids.iteritems():
449 tasknum = 1 461 bb.msg.note(1, bb.msg.domain.RunQueue, "%s: %s (%s)" % (tasknum, self.get_user_idstring(v, taskData), k))
462 tasknum = tasknum + 1
463 result = os.waitpid(-1, 0)
464 task = build_pids[result[0]]
465 if result[1] != 0:
466 bb.msg.error(bb.msg.domain.RunQueue, "Task %s (%s) failed" % (task, self.get_user_idstring(task, taskData)))
467 failed_fnids.append(self.runq_fnid[task])
468 del build_pids[result[0]]
469 active_builds = active_builds - 1
470 if len(failed_fnids) > 0:
471 return failed_fnids
472 except:
473 bb.msg.note(1, bb.msg.domain.RunQueue, "Sending SIGTERM to remaining %s tasks" % active_builds)
450 for k, v in build_pids.iteritems(): 474 for k, v in build_pids.iteritems():
451 bb.msg.note(1, bb.msg.domain.RunQueue, "%s: %s (%s)" % (tasknum, self.get_user_idstring(v, taskData), k)) 475 os.kill(k, signal.SIGTERM)
452 tasknum = tasknum + 1 476 raise
453 result = os.waitpid(-1, 0)
454 del build_pids[result[0]]
455 active_builds = active_builds - 1
456 raise
457 477
458 # Sanity Checks 478 # Sanity Checks
459 for task in range(len(self.runq_fnid)): 479 for task in range(len(self.runq_fnid)):
@@ -464,7 +484,7 @@ class RunQueue:
464 if runq_complete[task] == 0: 484 if runq_complete[task] == 0:
465 bb.msg.error(bb.msg.domain.RunQueue, "Task %s never completed!" % task) 485 bb.msg.error(bb.msg.domain.RunQueue, "Task %s never completed!" % task)
466 486
467 return 0 487 return failed_fnids
468 488
469 def dump_data(self, taskQueue): 489 def dump_data(self, taskQueue):
470 """ 490 """