From 8928df70eab1c7863d6ff0639418b6d25eb77c1e Mon Sep 17 00:00:00 2001
From: Zac Medico <zmedico@gentoo.org>
Date: Sat, 7 May 2011 22:58:33 -0700
Subject: [PATCH] Be careful with system pkgs + parallel-install.

This should prevent FEATURES=parallel-install from interfering with
the fixes from bug #256616 and bug #259954.
---
 pym/_emerge/Scheduler.py | 28 ++++++++++++++++++----------
 1 file changed, 18 insertions(+), 10 deletions(-)

diff --git a/pym/_emerge/Scheduler.py b/pym/_emerge/Scheduler.py
index 6c21c711e..fbf2d2dc0 100644
--- a/pym/_emerge/Scheduler.py
+++ b/pym/_emerge/Scheduler.py
@@ -3,6 +3,7 @@
 
 from __future__ import print_function
 
+from collections import deque
 import gc
 import gzip
 import logging
@@ -176,8 +177,9 @@ class Scheduler(PollScheduler):
 
 		# 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 = []
+		# on system packages are frequently unspecified. For example, see
+		# bug #256616.
+		self._merge_wait_queue = deque()
 		# 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
@@ -1644,14 +1646,19 @@ class Scheduler(PollScheduler):
 
 		while True:
 
-			# 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)
+			# When the number of jobs and merges drops to zero,
+			# process a single merge from _merge_wait_queue if
+			# it's not empty. We only process one since these are
+			# special packages and we want to ensure that
+			# parallel-install does not cause more than one of
+			# them to install at the same time.
+			if (self._merge_wait_queue and not self._jobs and
+				not self._task_queues.merge):
+				task = self._merge_wait_queue.popleft()
+				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._merge_wait_scheduled.append(task)
 
 			self._schedule_tasks_imp()
 			self._status_display.display()
@@ -1670,7 +1677,8 @@ class Scheduler(PollScheduler):
 				state_change += 1
 
 			if not (state_change or \
-				(not self._jobs and self._merge_wait_queue)):
+				(self._merge_wait_queue and not self._jobs and
+				not self._task_queues.merge)):
 				break
 
 		return self._keep_scheduling()
-- 
2.26.2