summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorZac Medico <zmedico@gentoo.org>2009-02-02 06:11:06 +0000
committerZac Medico <zmedico@gentoo.org>2009-02-02 06:11:06 +0000
commite589ece0600c449238d70f543eaba2f32a93ef5f (patch)
tree94df2029543a59c2095d3b6a900c8195ebf1ec51
parente9d6a559afab38ac687f17bb261a4ddde62a3247 (diff)
downloadportage-e589ece0600c449238d70f543eaba2f32a93ef5f.tar.gz
portage-e589ece0600c449238d70f543eaba2f32a93ef5f.tar.bz2
portage-e589ece0600c449238d70f543eaba2f32a93ef5f.zip
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. svn path=/main/trunk/; revision=12569
-rw-r--r--pym/_emerge/__init__.py38
1 files changed, 35 insertions, 3 deletions
diff --git a/pym/_emerge/__init__.py b/pym/_emerge/__init__.py
index fb04b304f..772a2df3f 100644
--- a/pym/_emerge/__init__.py
+++ b/pym/_emerge/__init__.py
@@ -9770,6 +9770,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")
@@ -10496,6 +10507,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)
@@ -10548,9 +10563,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")
@@ -10728,6 +10749,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()
@@ -10782,6 +10813,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)