1 |
Author: zmedico |
2 |
Date: 2009-02-02 06:11:06 +0000 (Mon, 02 Feb 2009) |
3 |
New Revision: 12569 |
4 |
|
5 |
Modified: |
6 |
main/trunk/pym/_emerge/__init__.py |
7 |
Log: |
8 |
Bug #256616 - Since dependencies on system packages are frequently unspecified, |
9 |
merge them only when no builds are executing. When a system package finishes |
10 |
building, it's added to a wait queue that is only processed when the number |
11 |
of running builds drops to zero. All pending merges are then processed before |
12 |
any new builds are allowed to start. |
13 |
|
14 |
|
15 |
Modified: main/trunk/pym/_emerge/__init__.py |
16 |
=================================================================== |
17 |
--- main/trunk/pym/_emerge/__init__.py 2009-02-02 01:03:47 UTC (rev 12568) |
18 |
+++ main/trunk/pym/_emerge/__init__.py 2009-02-02 06:11:06 UTC (rev 12569) |
19 |
@@ -9770,6 +9770,17 @@ |
20 |
for k in self._task_queues.allowed_keys: |
21 |
setattr(self._task_queues, k, |
22 |
SequentialTaskQueue()) |
23 |
+ |
24 |
+ # Holds merges that will wait to be executed when no builds are |
25 |
+ # executing. This is useful for system packages since dependencies |
26 |
+ # on system packages are frequently unspecified. |
27 |
+ self._merge_wait_queue = [] |
28 |
+ # Holds merges that have been transfered from the merge_wait_queue to |
29 |
+ # the actual merge queue. They are removed from this list upon |
30 |
+ # completion. Other packages can start building only when this list is |
31 |
+ # empty. |
32 |
+ self._merge_wait_scheduled = [] |
33 |
+ |
34 |
self._status_display = JobStatusDisplay() |
35 |
self._max_load = myopts.get("--load-average") |
36 |
max_jobs = myopts.get("--jobs") |
37 |
@@ -10496,6 +10507,10 @@ |
38 |
elif isinstance(pkg, Blocker): |
39 |
pass |
40 |
|
41 |
+ def _merge_wait_exit_handler(self, task): |
42 |
+ self._merge_wait_scheduled.remove(task) |
43 |
+ self._merge_exit(task) |
44 |
+ |
45 |
def _merge_exit(self, merge): |
46 |
self._do_merge_exit(merge) |
47 |
self._deallocate_config(merge.merge.settings) |
48 |
@@ -10548,9 +10563,15 @@ |
49 |
if build.returncode == os.EX_OK: |
50 |
self.curval += 1 |
51 |
merge = PackageMerge(merge=build) |
52 |
- merge.addExitListener(self._merge_exit) |
53 |
- self._task_queues.merge.add(merge) |
54 |
- self._status_display.merges = len(self._task_queues.merge) |
55 |
+ system_set = build.pkg.root_config.sets["system"] |
56 |
+ if system_set.findAtomForPackage(build.pkg): |
57 |
+ # Since dependencies on system packages are frequently |
58 |
+ # unspecified, merge them only when no builds are executing. |
59 |
+ self._merge_wait_queue.append(merge) |
60 |
+ else: |
61 |
+ merge.addExitListener(self._merge_exit) |
62 |
+ self._task_queues.merge.add(merge) |
63 |
+ self._status_display.merges = len(self._task_queues.merge) |
64 |
else: |
65 |
settings = build.settings |
66 |
build_dir = settings.get("PORTAGE_BUILDDIR") |
67 |
@@ -10728,6 +10749,16 @@ |
68 |
not (self._failed_pkgs and not self._build_opts.fetchonly)) |
69 |
|
70 |
def _schedule_tasks(self): |
71 |
+ |
72 |
+ # When the number of jobs drops to zero, process all waiting merges. |
73 |
+ if not self._jobs and self._merge_wait_queue: |
74 |
+ for task in self._merge_wait_queue: |
75 |
+ task.addExitListener(self._merge_wait_exit_handler) |
76 |
+ self._task_queues.merge.add(task) |
77 |
+ self._status_display.merges = len(self._task_queues.merge) |
78 |
+ self._merge_wait_scheduled.extend(self._merge_wait_queue) |
79 |
+ del self._merge_wait_queue[:] |
80 |
+ |
81 |
self._schedule_tasks_imp() |
82 |
self._status_display.display() |
83 |
|
84 |
@@ -10782,6 +10813,7 @@ |
85 |
return bool(state_change) |
86 |
|
87 |
if self._choose_pkg_return_early or \ |
88 |
+ self._merge_wait_scheduled or \ |
89 |
not self._can_add_job() or \ |
90 |
self._job_delay(): |
91 |
return bool(state_change) |