From: Zac Medico Date: Wed, 11 Mar 2009 03:32:45 +0000 (-0000) Subject: Bug #256616 - Since dependencies on system packages are frequently unspecified, X-Git-Tag: v2.1.6.8~227 X-Git-Url: http://git.tremily.us/?a=commitdiff_plain;h=5a2ebc46e4f1d0e6bdc0c5f723643db0507227cf;p=portage.git Bug #256616 - Since dependencies on system packages are frequently unspecified, merge them only when no builds are executing. When a system package finishes building, it's added to a wait queue that is only processed when the number of running builds drops to zero. All pending merges are then processed before any new builds are allowed to start. (trunk r12569) svn path=/main/branches/2.1.6/; revision=12850 --- diff --git a/pym/_emerge/__init__.py b/pym/_emerge/__init__.py index 26388a7f9..0d83d7cc5 100644 --- a/pym/_emerge/__init__.py +++ b/pym/_emerge/__init__.py @@ -9754,6 +9754,17 @@ class Scheduler(PollScheduler): for k in self._task_queues.allowed_keys: setattr(self._task_queues, k, SequentialTaskQueue()) + + # Holds merges that will wait to be executed when no builds are + # executing. This is useful for system packages since dependencies + # on system packages are frequently unspecified. + self._merge_wait_queue = [] + # Holds merges that have been transfered from the merge_wait_queue to + # the actual merge queue. They are removed from this list upon + # completion. Other packages can start building only when this list is + # empty. + self._merge_wait_scheduled = [] + self._status_display = JobStatusDisplay() self._max_load = myopts.get("--load-average") max_jobs = myopts.get("--jobs") @@ -10480,6 +10491,10 @@ class Scheduler(PollScheduler): elif isinstance(pkg, Blocker): pass + def _merge_wait_exit_handler(self, task): + self._merge_wait_scheduled.remove(task) + self._merge_exit(task) + def _merge_exit(self, merge): self._do_merge_exit(merge) self._deallocate_config(merge.merge.settings) @@ -10532,9 +10547,15 @@ class Scheduler(PollScheduler): if build.returncode == os.EX_OK: self.curval += 1 merge = PackageMerge(merge=build) - merge.addExitListener(self._merge_exit) - self._task_queues.merge.add(merge) - self._status_display.merges = len(self._task_queues.merge) + system_set = build.pkg.root_config.sets["system"] + if system_set.findAtomForPackage(build.pkg): + # Since dependencies on system packages are frequently + # unspecified, merge them only when no builds are executing. + self._merge_wait_queue.append(merge) + else: + merge.addExitListener(self._merge_exit) + self._task_queues.merge.add(merge) + self._status_display.merges = len(self._task_queues.merge) else: settings = build.settings build_dir = settings.get("PORTAGE_BUILDDIR") @@ -10712,6 +10733,16 @@ class Scheduler(PollScheduler): not (self._failed_pkgs and not self._build_opts.fetchonly)) def _schedule_tasks(self): + + # When the number of jobs drops to zero, process all waiting merges. + if not self._jobs and self._merge_wait_queue: + for task in self._merge_wait_queue: + task.addExitListener(self._merge_wait_exit_handler) + self._task_queues.merge.add(task) + self._status_display.merges = len(self._task_queues.merge) + self._merge_wait_scheduled.extend(self._merge_wait_queue) + del self._merge_wait_queue[:] + self._schedule_tasks_imp() self._status_display.display() @@ -10766,6 +10797,7 @@ class Scheduler(PollScheduler): return bool(state_change) if self._choose_pkg_return_early or \ + self._merge_wait_scheduled or \ not self._can_add_job() or \ self._job_delay(): return bool(state_change)