diff options
Diffstat (limited to 'bitbake/lib/bb/runqueue.py')
| -rw-r--r-- | bitbake/lib/bb/runqueue.py | 187 |
1 files changed, 88 insertions, 99 deletions
diff --git a/bitbake/lib/bb/runqueue.py b/bitbake/lib/bb/runqueue.py index 187720fc46..2b37619ae3 100644 --- a/bitbake/lib/bb/runqueue.py +++ b/bitbake/lib/bb/runqueue.py | |||
| @@ -22,13 +22,12 @@ Handles preparation and execution of a queue of tasks | |||
| 22 | # with this program; if not, write to the Free Software Foundation, Inc., | 22 | # with this program; if not, write to the Free Software Foundation, Inc., |
| 23 | # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. | 23 | # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. |
| 24 | 24 | ||
| 25 | import copy | ||
| 25 | import os | 26 | import os |
| 26 | import sys | 27 | import sys |
| 27 | import subprocess | ||
| 28 | import signal | 28 | import signal |
| 29 | import stat | 29 | import stat |
| 30 | import fcntl | 30 | import fcntl |
| 31 | import copy | ||
| 32 | import logging | 31 | import logging |
| 33 | import bb | 32 | import bb |
| 34 | from bb import msg, data, event | 33 | from bb import msg, data, event |
| @@ -36,12 +35,6 @@ from bb import msg, data, event | |||
| 36 | bblogger = logging.getLogger("BitBake") | 35 | bblogger = logging.getLogger("BitBake") |
| 37 | logger = logging.getLogger("BitBake.RunQueue") | 36 | logger = logging.getLogger("BitBake.RunQueue") |
| 38 | 37 | ||
| 39 | try: | ||
| 40 | import cPickle as pickle | ||
| 41 | except ImportError: | ||
| 42 | import pickle | ||
| 43 | logger.info("Importing cPickle failed. Falling back to a very slow implementation.") | ||
| 44 | |||
| 45 | class RunQueueStats: | 38 | class RunQueueStats: |
| 46 | """ | 39 | """ |
| 47 | Holds statistics on the tasks handled by the associated runQueue | 40 | Holds statistics on the tasks handled by the associated runQueue |
| @@ -93,28 +86,28 @@ class RunQueueScheduler(object): | |||
| 93 | """ | 86 | """ |
| 94 | self.rq = runqueue | 87 | self.rq = runqueue |
| 95 | self.rqdata = rqdata | 88 | self.rqdata = rqdata |
| 96 | numTasks = len(self.rq.runq_fnid) | 89 | numTasks = len(self.rqdata.runq_fnid) |
| 97 | 90 | ||
| 98 | self.prio_map = [] | 91 | self.prio_map = [] |
| 99 | self.prio_map.extend(range(numTasks)) | 92 | self.prio_map.extend(range(numTasks)) |
| 100 | 93 | ||
| 101 | def next_buildable_tasks(self): | 94 | def next_buildable_task(self): |
| 102 | """ | 95 | """ |
| 103 | Return the id of the first task we find that is buildable | 96 | Return the id of the first task we find that is buildable |
| 104 | """ | 97 | """ |
| 105 | for tasknum in range(len(self.rqdata.runq_fnid)): | 98 | for tasknum in xrange(len(self.rqdata.runq_fnid)): |
| 106 | taskid = self.prio_map[tasknum] | 99 | taskid = self.prio_map[tasknum] |
| 107 | if self.rq.runq_running[taskid] == 1: | 100 | if self.rq.runq_running[taskid] == 1: |
| 108 | continue | 101 | continue |
| 109 | if self.rq.runq_buildable[taskid] == 1: | 102 | if self.rq.runq_buildable[taskid] == 1: |
| 110 | yield taskid | 103 | return taskid |
| 111 | 104 | ||
| 112 | def next(self): | 105 | def next(self): |
| 113 | """ | 106 | """ |
| 114 | Return the id of the task we should build next | 107 | Return the id of the task we should build next |
| 115 | """ | 108 | """ |
| 116 | if self.rq.stats.active < self.rq.number_tasks: | 109 | if self.rq.stats.active < self.rq.number_tasks: |
| 117 | return next(self.next_buildable_tasks(), None) | 110 | return self.next_buildable_task() |
| 118 | 111 | ||
| 119 | class RunQueueSchedulerSpeed(RunQueueScheduler): | 112 | class RunQueueSchedulerSpeed(RunQueueScheduler): |
| 120 | """ | 113 | """ |
| @@ -127,13 +120,12 @@ class RunQueueSchedulerSpeed(RunQueueScheduler): | |||
| 127 | """ | 120 | """ |
| 128 | The priority map is sorted by task weight. | 121 | The priority map is sorted by task weight. |
| 129 | """ | 122 | """ |
| 130 | from copy import deepcopy | ||
| 131 | 123 | ||
| 132 | self.rq = runqueue | 124 | self.rq = runqueue |
| 133 | self.rqdata = rqdata | 125 | self.rqdata = rqdata |
| 134 | 126 | ||
| 135 | sortweight = sorted(deepcopy(self.rqdata.runq_weight)) | 127 | sortweight = sorted(copy.deepcopy(self.rqdata.runq_weight)) |
| 136 | copyweight = deepcopy(self.rqdata.runq_weight) | 128 | copyweight = copy.deepcopy(self.rqdata.runq_weight) |
| 137 | self.prio_map = [] | 129 | self.prio_map = [] |
| 138 | 130 | ||
| 139 | for weight in sortweight: | 131 | for weight in sortweight: |
| @@ -155,12 +147,11 @@ class RunQueueSchedulerCompletion(RunQueueSchedulerSpeed): | |||
| 155 | 147 | ||
| 156 | def __init__(self, runqueue, rqdata): | 148 | def __init__(self, runqueue, rqdata): |
| 157 | RunQueueSchedulerSpeed.__init__(self, runqueue, rqdata) | 149 | RunQueueSchedulerSpeed.__init__(self, runqueue, rqdata) |
| 158 | from copy import deepcopy | ||
| 159 | 150 | ||
| 160 | #FIXME - whilst this groups all fnids together it does not reorder the | 151 | #FIXME - whilst this groups all fnids together it does not reorder the |
| 161 | #fnid groups optimally. | 152 | #fnid groups optimally. |
| 162 | 153 | ||
| 163 | basemap = deepcopy(self.prio_map) | 154 | basemap = copy.deepcopy(self.prio_map) |
| 164 | self.prio_map = [] | 155 | self.prio_map = [] |
| 165 | while (len(basemap) > 0): | 156 | while (len(basemap) > 0): |
| 166 | entry = basemap.pop(0) | 157 | entry = basemap.pop(0) |
| @@ -190,25 +181,6 @@ class RunQueueData: | |||
| 190 | self.stampwhitelist = bb.data.getVar("BB_STAMP_WHITELIST", cfgData, 1) or "" | 181 | self.stampwhitelist = bb.data.getVar("BB_STAMP_WHITELIST", cfgData, 1) or "" |
| 191 | self.multi_provider_whitelist = (bb.data.getVar("MULTI_PROVIDER_WHITELIST", cfgData, 1) or "").split() | 182 | self.multi_provider_whitelist = (bb.data.getVar("MULTI_PROVIDER_WHITELIST", cfgData, 1) or "").split() |
| 192 | 183 | ||
| 193 | self.schedulers = set(obj for obj in globals().itervalues() | ||
| 194 | if type(obj) is type and issubclass(obj, RunQueueScheduler)) | ||
| 195 | |||
| 196 | user_schedulers = bb.data.getVar("BB_SCHEDULERS", cfgData, True) | ||
| 197 | if user_schedulers: | ||
| 198 | for sched in user_schedulers.split(): | ||
| 199 | if not "." in sched: | ||
| 200 | bb.note("Ignoring scheduler '%s' from BB_SCHEDULERS: not an import" % sched) | ||
| 201 | continue | ||
| 202 | |||
| 203 | modname, name = sched.rsplit(".", 1) | ||
| 204 | try: | ||
| 205 | module = __import__(modname, fromlist=(name,)) | ||
| 206 | except ImportError, exc: | ||
| 207 | logger.critical("Unable to import scheduler '%s' from '%s': %s" % (name, modname, exc)) | ||
| 208 | raise SystemExit(1) | ||
| 209 | else: | ||
| 210 | self.schedulers.add(getattr(module, name)) | ||
| 211 | |||
| 212 | self.reset() | 184 | self.reset() |
| 213 | 185 | ||
| 214 | def reset(self): | 186 | def reset(self): |
| @@ -313,7 +285,7 @@ class RunQueueData: | |||
| 313 | if dep in explored_deps[revdep]: | 285 | if dep in explored_deps[revdep]: |
| 314 | scan = True | 286 | scan = True |
| 315 | if scan: | 287 | if scan: |
| 316 | find_chains(revdep, deepcopy(prev_chain)) | 288 | find_chains(revdep, copy.deepcopy(prev_chain)) |
| 317 | for dep in explored_deps[revdep]: | 289 | for dep in explored_deps[revdep]: |
| 318 | if dep not in total_deps: | 290 | if dep not in total_deps: |
| 319 | total_deps.append(dep) | 291 | total_deps.append(dep) |
| @@ -715,20 +687,15 @@ class RunQueueData: | |||
| 715 | stampfnwhitelist.append(fn) | 687 | stampfnwhitelist.append(fn) |
| 716 | self.stampfnwhitelist = stampfnwhitelist | 688 | self.stampfnwhitelist = stampfnwhitelist |
| 717 | 689 | ||
| 718 | #self.dump_data(taskData) | ||
| 719 | |||
| 720 | # Interate over the task list looking for tasks with a 'setscene' function | 690 | # Interate over the task list looking for tasks with a 'setscene' function |
| 721 | |||
| 722 | self.runq_setscene = [] | 691 | self.runq_setscene = [] |
| 723 | for task in range(len(self.runq_fnid)): | 692 | for task in range(len(self.runq_fnid)): |
| 724 | setscene = taskData.gettask_id(self.taskData.fn_index[self.runq_fnid[task]], self.runq_task[task] + "_setscene", False) | 693 | setscene = taskData.gettask_id(self.taskData.fn_index[self.runq_fnid[task]], self.runq_task[task] + "_setscene", False) |
| 725 | if not setscene: | 694 | if not setscene: |
| 726 | continue | 695 | continue |
| 727 | #bb.note("Found setscene for %s %s" % (self.taskData.fn_index[self.runq_fnid[task]], self.runq_task[task])) | ||
| 728 | self.runq_setscene.append(task) | 696 | self.runq_setscene.append(task) |
| 729 | 697 | ||
| 730 | # Interate over the task list and call into the siggen code | 698 | # Interate over the task list and call into the siggen code |
| 731 | |||
| 732 | dealtwith = set() | 699 | dealtwith = set() |
| 733 | todeal = set(range(len(self.runq_fnid))) | 700 | todeal = set(range(len(self.runq_fnid))) |
| 734 | while len(todeal) > 0: | 701 | while len(todeal) > 0: |
| @@ -744,7 +711,7 @@ class RunQueueData: | |||
| 744 | hashdata = {} | 711 | hashdata = {} |
| 745 | hashdata["hashes"] = {} | 712 | hashdata["hashes"] = {} |
| 746 | hashdata["deps"] = {} | 713 | hashdata["deps"] = {} |
| 747 | for task in range(len(self.runq_fnid)): | 714 | for task in xrange(len(self.runq_fnid)): |
| 748 | hashdata["hashes"][self.taskData.fn_index[self.runq_fnid[task]] + "." + self.runq_task[task]] = self.runq_hash[task] | 715 | hashdata["hashes"][self.taskData.fn_index[self.runq_fnid[task]] + "." + self.runq_task[task]] = self.runq_hash[task] |
| 749 | deps = [] | 716 | deps = [] |
| 750 | for dep in self.runq_depends[task]: | 717 | for dep in self.runq_depends[task]: |
| @@ -764,24 +731,24 @@ class RunQueueData: | |||
| 764 | Dump some debug information on the internal data structures | 731 | Dump some debug information on the internal data structures |
| 765 | """ | 732 | """ |
| 766 | logger.debug(3, "run_tasks:") | 733 | logger.debug(3, "run_tasks:") |
| 767 | for task in range(len(self.rqdata.runq_task)): | 734 | for task in xrange(len(self.rqdata.runq_task)): |
| 768 | logger.debug(3, " (%s)%s - %s: %s Deps %s RevDeps %s" % (task, | 735 | logger.debug(3, " (%s)%s - %s: %s Deps %s RevDeps %s", task, |
| 769 | taskQueue.fn_index[self.rqdata.runq_fnid[task]], | 736 | taskQueue.fn_index[self.rqdata.runq_fnid[task]], |
| 770 | self.rqdata.runq_task[task], | 737 | self.rqdata.runq_task[task], |
| 771 | self.rqdata.runq_weight[task], | 738 | self.rqdata.runq_weight[task], |
| 772 | self.rqdata.runq_depends[task], | 739 | self.rqdata.runq_depends[task], |
| 773 | self.rqdata.runq_revdeps[task])) | 740 | self.rqdata.runq_revdeps[task]) |
| 774 | 741 | ||
| 775 | logger.debug(3, "sorted_tasks:") | 742 | logger.debug(3, "sorted_tasks:") |
| 776 | for task1 in range(len(self.rqdata.runq_task)): | 743 | for task1 in xrange(len(self.rqdata.runq_task)): |
| 777 | if task1 in self.prio_map: | 744 | if task1 in self.prio_map: |
| 778 | task = self.prio_map[task1] | 745 | task = self.prio_map[task1] |
| 779 | logger.debug(3, " (%s)%s - %s: %s Deps %s RevDeps %s" % (task, | 746 | logger.debug(3, " (%s)%s - %s: %s Deps %s RevDeps %s", task, |
| 780 | taskQueue.fn_index[self.rqdata.runq_fnid[task]], | 747 | taskQueue.fn_index[self.rqdata.runq_fnid[task]], |
| 781 | self.rqdata.runq_task[task], | 748 | self.rqdata.runq_task[task], |
| 782 | self.rqdata.runq_weight[task], | 749 | self.rqdata.runq_weight[task], |
| 783 | self.rqdata.runq_depends[task], | 750 | self.rqdata.runq_depends[task], |
| 784 | self.rqdata.runq_revdeps[task])) | 751 | self.rqdata.runq_revdeps[task]) |
| 785 | 752 | ||
| 786 | class RunQueue: | 753 | class RunQueue: |
| 787 | def __init__(self, cooker, cfgData, dataCache, taskData, targets): | 754 | def __init__(self, cooker, cfgData, dataCache, taskData, targets): |
| @@ -809,7 +776,7 @@ class RunQueue: | |||
| 809 | if self.stamppolicy == "whitelist": | 776 | if self.stamppolicy == "whitelist": |
| 810 | stampwhitelist = self.rqdata.stampfnwhitelist | 777 | stampwhitelist = self.rqdata.stampfnwhitelist |
| 811 | 778 | ||
| 812 | for task in range(len(self.rqdata.runq_fnid)): | 779 | for task in xrange(len(self.rqdata.runq_fnid)): |
| 813 | unchecked[task] = "" | 780 | unchecked[task] = "" |
| 814 | if len(self.rqdata.runq_depends[task]) == 0: | 781 | if len(self.rqdata.runq_depends[task]) == 0: |
| 815 | buildable.append(task) | 782 | buildable.append(task) |
| @@ -824,7 +791,7 @@ class RunQueue: | |||
| 824 | if revdep in unchecked: | 791 | if revdep in unchecked: |
| 825 | buildable.append(revdep) | 792 | buildable.append(revdep) |
| 826 | 793 | ||
| 827 | for task in range(len(self.rqdata.runq_fnid)): | 794 | for task in xrange(len(self.rqdata.runq_fnid)): |
| 828 | if task not in unchecked: | 795 | if task not in unchecked: |
| 829 | continue | 796 | continue |
| 830 | fn = self.rqdata.taskData.fn_index[self.rqdata.runq_fnid[task]] | 797 | fn = self.rqdata.taskData.fn_index[self.rqdata.runq_fnid[task]] |
| @@ -909,7 +876,7 @@ class RunQueue: | |||
| 909 | fn = self.rqdata.taskData.fn_index[self.rqdata.runq_fnid[task]] | 876 | fn = self.rqdata.taskData.fn_index[self.rqdata.runq_fnid[task]] |
| 910 | if taskname is None: | 877 | if taskname is None: |
| 911 | taskname = self.rqdata.runq_task[task] | 878 | taskname = self.rqdata.runq_task[task] |
| 912 | 879 | ||
| 913 | stampfile = bb.parse.siggen.stampfile(self.rqdata.dataCache.stamp[fn], fn, taskname) | 880 | stampfile = bb.parse.siggen.stampfile(self.rqdata.dataCache.stamp[fn], fn, taskname) |
| 914 | 881 | ||
| 915 | # If the stamp is missing its not current | 882 | # If the stamp is missing its not current |
| @@ -919,7 +886,7 @@ class RunQueue: | |||
| 919 | # If its a 'nostamp' task, it's not current | 886 | # If its a 'nostamp' task, it's not current |
| 920 | taskdep = self.rqdata.dataCache.task_deps[fn] | 887 | taskdep = self.rqdata.dataCache.task_deps[fn] |
| 921 | if 'nostamp' in taskdep and taskname in taskdep['nostamp']: | 888 | if 'nostamp' in taskdep and taskname in taskdep['nostamp']: |
| 922 | logger.debug(2, "%s.%s is nostamp\n" % (fn, taskname)) | 889 | logger.debug(2, "%s.%s is nostamp\n", fn, taskname) |
| 923 | return False | 890 | return False |
| 924 | 891 | ||
| 925 | if taskname != "do_setscene" and taskname.endswith("_setscene"): | 892 | if taskname != "do_setscene" and taskname.endswith("_setscene"): |
| @@ -939,10 +906,10 @@ class RunQueue: | |||
| 939 | continue | 906 | continue |
| 940 | if fn == fn2 or (fulldeptree and fn2 not in stampwhitelist): | 907 | if fn == fn2 or (fulldeptree and fn2 not in stampwhitelist): |
| 941 | if not t2: | 908 | if not t2: |
| 942 | logger.debug(2, "Stampfile %s does not exist" % (stampfile2)) | 909 | logger.debug(2, 'Stampfile %s does not exist', stampfile2) |
| 943 | iscurrent = False | 910 | iscurrent = False |
| 944 | if t1 < t2: | 911 | if t1 < t2: |
| 945 | logger.debug(2, "Stampfile %s < %s" % (stampfile, stampfile2)) | 912 | logger.debug(2, 'Stampfile %s < %s', stampfile, stampfile2) |
| 946 | iscurrent = False | 913 | iscurrent = False |
| 947 | 914 | ||
| 948 | return iscurrent | 915 | return iscurrent |
| @@ -1014,7 +981,7 @@ class RunQueue: | |||
| 1014 | bb.note("Reparsing files to collect dependency data") | 981 | bb.note("Reparsing files to collect dependency data") |
| 1015 | for task in range(len(self.rqdata.runq_fnid)): | 982 | for task in range(len(self.rqdata.runq_fnid)): |
| 1016 | if self.rqdata.runq_fnid[task] not in done: | 983 | if self.rqdata.runq_fnid[task] not in done: |
| 1017 | fn = self.rqdata.taskData.fn_index[self.rqdata.runq_fnid[task]] | 984 | fn = self.rqdata.taskData.fn_index[self.rqdata.runq_fnid[task]] |
| 1018 | the_data = bb.cache.Cache.loadDataFull(fn, self.cooker.get_file_appends(fn), self.cooker.configuration.data) | 985 | the_data = bb.cache.Cache.loadDataFull(fn, self.cooker.get_file_appends(fn), self.cooker.configuration.data) |
| 1019 | done.add(self.rqdata.runq_fnid[task]) | 986 | done.add(self.rqdata.runq_fnid[task]) |
| 1020 | 987 | ||
| @@ -1087,7 +1054,7 @@ class RunQueueExecute: | |||
| 1087 | self.rq.state = runQueueComplete | 1054 | self.rq.state = runQueueComplete |
| 1088 | return | 1055 | return |
| 1089 | 1056 | ||
| 1090 | def fork_off_task(self, fn, task, taskname): | 1057 | def fork_off_task(self, fn, task, taskname, quieterrors=False): |
| 1091 | the_data = bb.cache.Cache.loadDataFull(fn, self.cooker.get_file_appends(fn), self.cooker.configuration.data) | 1058 | the_data = bb.cache.Cache.loadDataFull(fn, self.cooker.get_file_appends(fn), self.cooker.configuration.data) |
| 1092 | 1059 | ||
| 1093 | env = bb.data.export_vars(the_data) | 1060 | env = bb.data.export_vars(the_data) |
| @@ -1115,10 +1082,9 @@ class RunQueueExecute: | |||
| 1115 | sys.stdout.flush() | 1082 | sys.stdout.flush() |
| 1116 | sys.stderr.flush() | 1083 | sys.stderr.flush() |
| 1117 | try: | 1084 | try: |
| 1118 | pipeinfd, pipeoutfd = os.pipe() | 1085 | pipein, pipeout = os.pipe() |
| 1119 | pipein = os.fdopen(pipeinfd, 'rb', 4096) | 1086 | pipein = os.fdopen(pipein, 'rb', 4096) |
| 1120 | pipeout = os.fdopen(pipeoutfd, 'wb', 4096) | 1087 | pipeout = os.fdopen(pipeout, 'wb', 0) |
| 1121 | |||
| 1122 | pid = os.fork() | 1088 | pid = os.fork() |
| 1123 | except OSError as e: | 1089 | except OSError as e: |
| 1124 | bb.msg.fatal(bb.msg.domain.RunQueue, "fork failed: %d (%s)" % (e.errno, e.strerror)) | 1090 | bb.msg.fatal(bb.msg.domain.RunQueue, "fork failed: %d (%s)" % (e.errno, e.strerror)) |
| @@ -1148,7 +1114,7 @@ class RunQueueExecute: | |||
| 1148 | #newso = open(logout, 'w') | 1114 | #newso = open(logout, 'w') |
| 1149 | #os.dup2(newso.fileno(), sys.stdout.fileno()) | 1115 | #os.dup2(newso.fileno(), sys.stdout.fileno()) |
| 1150 | #os.dup2(newso.fileno(), sys.stderr.fileno()) | 1116 | #os.dup2(newso.fileno(), sys.stderr.fileno()) |
| 1151 | if taskname.endswith("_setscene"): | 1117 | if quieterrors: |
| 1152 | the_data.setVarFlag(taskname, "quieterrors", "1") | 1118 | the_data.setVarFlag(taskname, "quieterrors", "1") |
| 1153 | 1119 | ||
| 1154 | bb.data.setVar("BB_WORKERCONTEXT", "1", the_data) | 1120 | bb.data.setVar("BB_WORKERCONTEXT", "1", the_data) |
| @@ -1219,14 +1185,38 @@ class RunQueueExecuteTasks(RunQueueExecute): | |||
| 1219 | 1185 | ||
| 1220 | event.fire(bb.event.StampUpdate(self.rqdata.target_pairs, self.rqdata.dataCache.stamp), self.cfgData) | 1186 | event.fire(bb.event.StampUpdate(self.rqdata.target_pairs, self.rqdata.dataCache.stamp), self.cfgData) |
| 1221 | 1187 | ||
| 1222 | for scheduler in self.rqdata.schedulers: | 1188 | schedulers = self.get_schedulers() |
| 1189 | for scheduler in schedulers: | ||
| 1223 | if self.scheduler == scheduler.name: | 1190 | if self.scheduler == scheduler.name: |
| 1224 | self.sched = scheduler(self, self.rqdata) | 1191 | self.sched = scheduler(self, self.rqdata) |
| 1225 | logger.debug(1, "Using runqueue scheduler '%s'", scheduler.name) | 1192 | logger.debug(1, "Using runqueue scheduler '%s'", scheduler.name) |
| 1226 | break | 1193 | break |
| 1227 | else: | 1194 | else: |
| 1228 | bb.fatal("Invalid scheduler '%s'. Available schedulers: %s" % | 1195 | bb.fatal("Invalid scheduler '%s'. Available schedulers: %s" % |
| 1229 | (self.scheduler, ", ".join(obj.name for obj in self.rqdata.schedulers))) | 1196 | (self.scheduler, ", ".join(obj.name for obj in schedulers))) |
| 1197 | |||
| 1198 | |||
| 1199 | def get_schedulers(self): | ||
| 1200 | schedulers = set(obj for obj in globals().values() | ||
| 1201 | if type(obj) is type and | ||
| 1202 | issubclass(obj, RunQueueScheduler)) | ||
| 1203 | |||
| 1204 | user_schedulers = bb.data.getVar("BB_SCHEDULERS", self.cfgData, True) | ||
| 1205 | if user_schedulers: | ||
| 1206 | for sched in user_schedulers.split(): | ||
| 1207 | if not "." in sched: | ||
| 1208 | bb.note("Ignoring scheduler '%s' from BB_SCHEDULERS: not an import" % sched) | ||
| 1209 | continue | ||
| 1210 | |||
| 1211 | modname, name = sched.rsplit(".", 1) | ||
| 1212 | try: | ||
| 1213 | module = __import__(modname, fromlist=(name,)) | ||
| 1214 | except ImportError, exc: | ||
| 1215 | logger.critical("Unable to import scheduler '%s' from '%s': %s" % (name, modname, exc)) | ||
| 1216 | raise SystemExit(1) | ||
| 1217 | else: | ||
| 1218 | schedulers.add(getattr(module, name)) | ||
| 1219 | return schedulers | ||
| 1230 | 1220 | ||
| 1231 | def task_completeoutright(self, task): | 1221 | def task_completeoutright(self, task): |
| 1232 | """ | 1222 | """ |
| @@ -1283,17 +1273,17 @@ class RunQueueExecuteTasks(RunQueueExecute): | |||
| 1283 | # nothing to do | 1273 | # nothing to do |
| 1284 | self.rq.state = runQueueCleanUp | 1274 | self.rq.state = runQueueCleanUp |
| 1285 | 1275 | ||
| 1286 | for task in iter(self.sched.next, None): | 1276 | task = self.sched.next() |
| 1277 | if task is not None: | ||
| 1287 | fn = self.rqdata.taskData.fn_index[self.rqdata.runq_fnid[task]] | 1278 | fn = self.rqdata.taskData.fn_index[self.rqdata.runq_fnid[task]] |
| 1288 | 1279 | ||
| 1289 | taskname = self.rqdata.runq_task[task] | 1280 | taskname = self.rqdata.runq_task[task] |
| 1290 | if self.rq.check_stamp_task(task, taskname): | 1281 | if self.rq.check_stamp_task(task, taskname): |
| 1291 | logger.debug(2, "Stamp current task %s (%s)" % (task, self.rqdata.get_user_idstring(task))) | 1282 | logger.debug(2, "Stamp current task %s (%s)", task, |
| 1283 | self.rqdata.get_user_idstring(task)) | ||
| 1292 | self.task_skip(task) | 1284 | self.task_skip(task) |
| 1293 | return True | 1285 | return True |
| 1294 | 1286 | ||
| 1295 | bb.event.fire(runQueueTaskStarted(task, self.stats, self.rq), self.cfgData) | ||
| 1296 | |||
| 1297 | taskdep = self.rqdata.dataCache.task_deps[fn] | 1287 | taskdep = self.rqdata.dataCache.task_deps[fn] |
| 1298 | if 'noexec' in taskdep and taskname in taskdep['noexec']: | 1288 | if 'noexec' in taskdep and taskname in taskdep['noexec']: |
| 1299 | startevent = runQueueTaskStarted(task, self.stats, self.rq, | 1289 | startevent = runQueueTaskStarted(task, self.stats, self.rq, |
| @@ -1457,12 +1447,11 @@ class RunQueueExecuteScenequeue(RunQueueExecute): | |||
| 1457 | 1447 | ||
| 1458 | for task in xrange(len(self.sq_revdeps)): | 1448 | for task in xrange(len(self.sq_revdeps)): |
| 1459 | if task not in valid_new and task not in noexec: | 1449 | if task not in valid_new and task not in noexec: |
| 1460 | logger.debug(2, "No package found so skipping setscene task %s" % (self.rqdata.get_user_idstring(self.rqdata.runq_setscene[task]))) | 1450 | logger.debug(2, 'No package found, so skipping setscene task %s', |
| 1451 | self.rqdata.get_user_idstring(task)) | ||
| 1461 | self.task_failoutright(task) | 1452 | self.task_failoutright(task) |
| 1462 | 1453 | ||
| 1463 | #print(str(valid)) | 1454 | logger.info('Executing SetScene Tasks') |
| 1464 | |||
| 1465 | logger.info("Executing SetScene Tasks") | ||
| 1466 | 1455 | ||
| 1467 | self.rq.state = runQueueSceneRun | 1456 | self.rq.state = runQueueSceneRun |
| 1468 | 1457 | ||
| @@ -1523,11 +1512,6 @@ class RunQueueExecuteScenequeue(RunQueueExecute): | |||
| 1523 | # Find the next setscene to run | 1512 | # Find the next setscene to run |
| 1524 | for nexttask in xrange(self.stats.total): | 1513 | for nexttask in xrange(self.stats.total): |
| 1525 | if self.runq_buildable[nexttask] == 1 and self.runq_running[nexttask] != 1: | 1514 | if self.runq_buildable[nexttask] == 1 and self.runq_running[nexttask] != 1: |
| 1526 | #bb.note("Comparing %s to %s" % (self.sq_revdeps[nexttask], self.scenequeue_covered)) | ||
| 1527 | #if len(self.sq_revdeps[nexttask]) > 0 and self.sq_revdeps[nexttask].issubset(self.scenequeue_covered): | ||
| 1528 | # bb.note("Skipping task %s" % nexttask) | ||
| 1529 | # self.scenequeue_skip(nexttask) | ||
| 1530 | # return True | ||
| 1531 | task = nexttask | 1515 | task = nexttask |
| 1532 | break | 1516 | break |
| 1533 | if task is not None: | 1517 | if task is not None: |
| @@ -1536,7 +1520,8 @@ class RunQueueExecuteScenequeue(RunQueueExecute): | |||
| 1536 | 1520 | ||
| 1537 | taskname = self.rqdata.runq_task[realtask] + "_setscene" | 1521 | taskname = self.rqdata.runq_task[realtask] + "_setscene" |
| 1538 | if self.rq.check_stamp_task(realtask, self.rqdata.runq_task[realtask]): | 1522 | if self.rq.check_stamp_task(realtask, self.rqdata.runq_task[realtask]): |
| 1539 | logger.debug(2, "Stamp for underlying task %s (%s) is current so skipping setscene varient" % (task, self.rqdata.get_user_idstring(task))) | 1523 | logger.debug(2, 'Stamp for underlying task %s(%s) is current, so skipping setscene variant', |
| 1524 | task, self.rqdata.get_user_idstring(task)) | ||
| 1540 | self.task_failoutright(task) | 1525 | self.task_failoutright(task) |
| 1541 | return True | 1526 | return True |
| 1542 | 1527 | ||
| @@ -1547,7 +1532,8 @@ class RunQueueExecuteScenequeue(RunQueueExecute): | |||
| 1547 | return True | 1532 | return True |
| 1548 | 1533 | ||
| 1549 | if self.rq.check_stamp_task(realtask, taskname): | 1534 | if self.rq.check_stamp_task(realtask, taskname): |
| 1550 | logger.debug(2, "Setscene stamp current task %s (%s) so skip it and its dependencies" % (task, self.rqdata.get_user_idstring(realtask))) | 1535 | logger.debug(2, 'Setscene stamp current task %s(%s), so skip it and its dependencies', |
| 1536 | task, self.rqdata.get_user_idstring(realtask)) | ||
| 1551 | self.task_skip(task) | 1537 | self.task_skip(task) |
| 1552 | return True | 1538 | return True |
| 1553 | 1539 | ||
| @@ -1577,11 +1563,14 @@ class RunQueueExecuteScenequeue(RunQueueExecute): | |||
| 1577 | for task in oldcovered: | 1563 | for task in oldcovered: |
| 1578 | self.rq.scenequeue_covered.add(self.rqdata.runq_setscene[task]) | 1564 | self.rq.scenequeue_covered.add(self.rqdata.runq_setscene[task]) |
| 1579 | 1565 | ||
| 1580 | bb.debug(1, "We can skip tasks %s" % self.rq.scenequeue_covered) | 1566 | logger.debug(1, 'We can skip tasks %s', self.rq.scenequeue_covered) |
| 1581 | 1567 | ||
| 1582 | self.rq.state = runQueueRunInit | 1568 | self.rq.state = runQueueRunInit |
| 1583 | return True | 1569 | return True |
| 1584 | 1570 | ||
| 1571 | def fork_off_task(self, fn, task, taskname): | ||
| 1572 | return RunQueueExecute.fork_off_task(self, fn, task, taskname, quieterrors=True) | ||
| 1573 | |||
| 1585 | class TaskFailure(Exception): | 1574 | class TaskFailure(Exception): |
| 1586 | """ | 1575 | """ |
| 1587 | Exception raised when a task in a runqueue fails | 1576 | Exception raised when a task in a runqueue fails |
| @@ -1632,12 +1621,12 @@ class runQueueTaskCompleted(runQueueEvent): | |||
| 1632 | """ | 1621 | """ |
| 1633 | 1622 | ||
| 1634 | #def check_stamp_fn(fn, taskname, d): | 1623 | #def check_stamp_fn(fn, taskname, d): |
| 1635 | # rq = bb.data.getVar("__RUNQUEUE_DO_NOT_USE_EXTERNALLY", d) | 1624 | # rqexe = bb.data.getVar("__RUNQUEUE_DO_NOT_USE_EXTERNALLY", d) |
| 1636 | # fn = bb.data.getVar("__RUNQUEUE_DO_NOT_USE_EXTERNALLY2", d) | 1625 | # fn = bb.data.getVar("__RUNQUEUE_DO_NOT_USE_EXTERNALLY2", d) |
| 1637 | # fnid = rq.rqdata.taskData.getfn_id(fn) | 1626 | # fnid = rqexe.rqdata.taskData.getfn_id(fn) |
| 1638 | # taskid = rq.get_task_id(fnid, taskname) | 1627 | # taskid = rqexe.rqdata.get_task_id(fnid, taskname) |
| 1639 | # if taskid is not None: | 1628 | # if taskid is not None: |
| 1640 | # return rq.check_stamp_task(taskid) | 1629 | # return rqexe.rq.check_stamp_task(taskid) |
| 1641 | # return None | 1630 | # return None |
| 1642 | 1631 | ||
| 1643 | class runQueuePipe(): | 1632 | class runQueuePipe(): |
| @@ -1645,17 +1634,17 @@ class runQueuePipe(): | |||
| 1645 | Abstraction for a pipe between a worker thread and the server | 1634 | Abstraction for a pipe between a worker thread and the server |
| 1646 | """ | 1635 | """ |
| 1647 | def __init__(self, pipein, pipeout, d): | 1636 | def __init__(self, pipein, pipeout, d): |
| 1648 | self.fd = pipein | 1637 | self.input = pipein |
| 1649 | pipeout.close() | 1638 | pipeout.close() |
| 1650 | fcntl.fcntl(self.fd, fcntl.F_SETFL, fcntl.fcntl(self.fd, fcntl.F_GETFL) | os.O_NONBLOCK) | 1639 | fcntl.fcntl(self.input, fcntl.F_SETFL, fcntl.fcntl(self.input, fcntl.F_GETFL) | os.O_NONBLOCK) |
| 1651 | self.queue = "" | 1640 | self.queue = "" |
| 1652 | self.d = d | 1641 | self.d = d |
| 1653 | 1642 | ||
| 1654 | def read(self): | 1643 | def read(self): |
| 1655 | start = len(self.queue) | 1644 | start = len(self.queue) |
| 1656 | try: | 1645 | try: |
| 1657 | self.queue = self.queue + self.fd.read(1024) | 1646 | self.queue = self.queue + self.input.read(1024) |
| 1658 | except IOError: | 1647 | except (OSError, IOError): |
| 1659 | pass | 1648 | pass |
| 1660 | end = len(self.queue) | 1649 | end = len(self.queue) |
| 1661 | index = self.queue.find("</event>") | 1650 | index = self.queue.find("</event>") |
| @@ -1670,4 +1659,4 @@ class runQueuePipe(): | |||
| 1670 | continue | 1659 | continue |
| 1671 | if len(self.queue) > 0: | 1660 | if len(self.queue) > 0: |
| 1672 | print("Warning, worker left partial message: %s" % self.queue) | 1661 | print("Warning, worker left partial message: %s" % self.queue) |
| 1673 | self.fd.close() | 1662 | self.input.close() |
