summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorZac Medico <zmedico@gentoo.org>2008-07-09 02:15:19 +0000
committerZac Medico <zmedico@gentoo.org>2008-07-09 02:15:19 +0000
commita91d697e8419eed4fbb5a27daf35f297cc9c5689 (patch)
tree067b57815f16dd7cdb3336076bd224a470465fb6
parentade72eb9c45b38c3d1bf8e68de88854563eea033 (diff)
downloadportage-a91d697e8419eed4fbb5a27daf35f297cc9c5689.tar.gz
portage-a91d697e8419eed4fbb5a27daf35f297cc9c5689.tar.bz2
portage-a91d697e8419eed4fbb5a27daf35f297cc9c5689.zip
Fix Scheduler._choose_pkg() to perform uninstallation actions (due to
blockers) in the correct order when building in parallel. svn path=/main/trunk/; revision=10996
-rw-r--r--pym/_emerge/__init__.py30
1 files changed, 25 insertions, 5 deletions
diff --git a/pym/_emerge/__init__.py b/pym/_emerge/__init__.py
index cd43593de..1c652e691 100644
--- a/pym/_emerge/__init__.py
+++ b/pym/_emerge/__init__.py
@@ -7710,8 +7710,31 @@ class Scheduler(object):
return
self._digraph = digraph
+ self._reverse_uninstall_edges()
self._prune_digraph()
+ def _reverse_uninstall_edges(self):
+ """
+ The uninstall is performed only after blocking packages have been
+ merged on top of it (similar to how a normal upgrade is performed
+ by first merging the new version on top of the onld version). This
+ is implemented by reversing the the parent -> uninstall edges in
+ the graph.
+ """
+
+ graph = self._digraph
+
+ for node in self._mergelist:
+ if not isinstance(node, Package) or \
+ node.operation != "uninstall":
+ continue
+
+ parent_nodes = graph.parent_nodes(node)
+ graph.remove(node)
+ for blocked_pkg in parent_nodes:
+ graph.add(blocked_pkg, node,
+ priority=BlockerDepPriority.instance)
+
def _prune_digraph(self):
"""
Prune any root nodes that are irrelevant.
@@ -8104,18 +8127,15 @@ class Scheduler(object):
def _choose_pkg(self):
"""
- TODO: fix order for uninstall operations
+ Choose a task that has all it's dependencies satisfied.
"""
- if self._max_jobs < 2 or self._jobs == 0 or \
- self._pkg_queue[0].operation == "uninstall":
+ if self._max_jobs < 2 or self._jobs == 0:
return self._pkg_queue.pop(0)
self._prune_digraph()
chosen_pkg = None
for pkg in self._pkg_queue:
- if pkg.operation == "uninstall":
- continue
if not self._dependent_on_scheduled_merges(pkg):
chosen_pkg = pkg
break