1 |
Author: zmedico |
2 |
Date: 2008-06-29 17:27:37 +0000 (Sun, 29 Jun 2008) |
3 |
New Revision: 10851 |
4 |
|
5 |
Modified: |
6 |
main/trunk/pym/_emerge/__init__.py |
7 |
Log: |
8 |
Centralize select.poll() event handling in MergeTask._schedule(). This will |
9 |
allow the parent process to handle output of multiple child processes |
10 |
running in parllel. |
11 |
|
12 |
|
13 |
Modified: main/trunk/pym/_emerge/__init__.py |
14 |
=================================================================== |
15 |
--- main/trunk/pym/_emerge/__init__.py 2008-06-29 15:08:37 UTC (rev 10850) |
16 |
+++ main/trunk/pym/_emerge/__init__.py 2008-06-29 17:27:37 UTC (rev 10851) |
17 |
@@ -20,6 +20,8 @@ |
18 |
except KeyboardInterrupt: |
19 |
sys.exit(1) |
20 |
|
21 |
+import array |
22 |
+import select |
23 |
import gc |
24 |
import os, stat |
25 |
import platform |
26 |
@@ -1527,7 +1529,7 @@ |
27 |
""" |
28 |
TODO: Support asynchronous execution, to implement parallel builds. |
29 |
""" |
30 |
- __slots__ = ("pkg", "settings") |
31 |
+ __slots__ = ("pkg", "register", "schedule", "settings", "unregister") |
32 |
|
33 |
_phases = ("setup", "unpack", "compile", "test", "install") |
34 |
|
35 |
@@ -1562,9 +1564,10 @@ |
36 |
|
37 |
for mydo in self._phases: |
38 |
ebuild_phase = EbuildPhase(fd_pipes=fd_pipes, |
39 |
- pkg=self.pkg, phase=mydo, settings=settings) |
40 |
+ pkg=self.pkg, phase=mydo, register=self.register, |
41 |
+ settings=settings, unregister=self.unregister) |
42 |
ebuild_phase.start() |
43 |
- ebuild_phase._output_handler() |
44 |
+ self.schedule() |
45 |
retval = ebuild_phase.wait() |
46 |
|
47 |
portage._post_phase_userpriv_perms(settings) |
48 |
@@ -1580,7 +1583,8 @@ |
49 |
|
50 |
class EbuildPhase(SlotObject): |
51 |
|
52 |
- __slots__ = ("fd_pipes", "phase", "pkg", "settings", |
53 |
+ __slots__ = ("fd_pipes", "phase", "pkg", |
54 |
+ "register", "settings", "unregister", |
55 |
"pid", "returncode", "files") |
56 |
|
57 |
_file_names = ("log", "stdout", "ebuild") |
58 |
@@ -1662,40 +1666,25 @@ |
59 |
files["log"] = open(logfile, 'a') |
60 |
files["stdout"] = os.fdopen(os.dup(fd_pipes_orig[1]), 'w') |
61 |
files["ebuild"] = os.fdopen(master_fd, 'r') |
62 |
+ self.register(files["ebuild"].fileno(), |
63 |
+ select.POLLIN, self._output_handler) |
64 |
|
65 |
- def _output_handler(self): |
66 |
- log_file = self.files.get("log") |
67 |
- if log_file is None: |
68 |
- return |
69 |
- ebuild_file = self.files["ebuild"] |
70 |
- stdout_file = self.files["stdout"] |
71 |
- iwtd = [ebuild_file] |
72 |
- owtd = [] |
73 |
- ewtd = [] |
74 |
- import array, select |
75 |
- buffsize = self._bufsize |
76 |
- eof = False |
77 |
- while not eof: |
78 |
- events = select.select(iwtd, owtd, ewtd) |
79 |
- for f in events[0]: |
80 |
- # Use non-blocking mode to prevent read |
81 |
- # calls from blocking indefinitely. |
82 |
- buf = array.array('B') |
83 |
- try: |
84 |
- buf.fromfile(f, buffsize) |
85 |
- except EOFError: |
86 |
- pass |
87 |
- if not buf: |
88 |
- eof = True |
89 |
- break |
90 |
- if f is ebuild_file: |
91 |
- buf.tofile(stdout_file) |
92 |
- stdout_file.flush() |
93 |
- buf.tofile(log_file) |
94 |
- log_file.flush() |
95 |
- log_file.close() |
96 |
- stdout_file.close() |
97 |
- ebuild_file.close() |
98 |
+ def _output_handler(self, fd, event): |
99 |
+ files = self.files |
100 |
+ buf = array.array('B') |
101 |
+ try: |
102 |
+ buf.fromfile(files["ebuild"], self._bufsize) |
103 |
+ except EOFError: |
104 |
+ pass |
105 |
+ if buf: |
106 |
+ buf.tofile(files["stdout"]) |
107 |
+ files["stdout"].flush() |
108 |
+ buf.tofile(files["log"]) |
109 |
+ files["log"].flush() |
110 |
+ else: |
111 |
+ self.unregister(files["ebuild"].fileno()) |
112 |
+ for f in files.values(): |
113 |
+ f.close() |
114 |
|
115 |
def wait(self): |
116 |
pid = self.pid |
117 |
@@ -6357,6 +6346,8 @@ |
118 |
clone=trees[root]["vartree"].settings) |
119 |
self.curval = 0 |
120 |
self._spawned_pids = [] |
121 |
+ self._poll_event_handlers = {} |
122 |
+ self._poll = select.poll() |
123 |
|
124 |
class _pkg_failure(portage.exception.PortageException): |
125 |
""" |
126 |
@@ -6521,6 +6512,19 @@ |
127 |
pass |
128 |
spawned_pids.remove(pid) |
129 |
|
130 |
+ def _register(self, f, eventmask, handler): |
131 |
+ self._poll_event_handlers[f] = handler |
132 |
+ self._poll.register(f, eventmask) |
133 |
+ |
134 |
+ def _unregister(self, f): |
135 |
+ self._poll.unregister(f) |
136 |
+ del self._poll_event_handlers[f] |
137 |
+ |
138 |
+ def _schedule(self): |
139 |
+ while self._poll_event_handlers: |
140 |
+ for f, event in self._poll.poll(): |
141 |
+ self._poll_event_handlers[f](f, event) |
142 |
+ |
143 |
def _merge(self): |
144 |
mylist = self._mergelist |
145 |
favorites = self._favorites |
146 |
@@ -6759,7 +6763,9 @@ |
147 |
(mergecount, len(mymergelist), pkg_key) |
148 |
emergelog(xterm_titles, msg, short_msg=short_msg) |
149 |
|
150 |
- build = EbuildBuild(pkg=pkg, settings=pkgsettings) |
151 |
+ build = EbuildBuild(pkg=pkg, register=self._register, |
152 |
+ schedule=self._schedule, settings=pkgsettings, |
153 |
+ unregister=self._unregister) |
154 |
retval = build.execute() |
155 |
if retval != os.EX_OK: |
156 |
raise self._pkg_failure(retval) |
157 |
@@ -6794,7 +6800,9 @@ |
158 |
(mergecount, len(mymergelist), pkg_key) |
159 |
emergelog(xterm_titles, msg, short_msg=short_msg) |
160 |
|
161 |
- build = EbuildBuild(pkg=pkg, settings=pkgsettings) |
162 |
+ build = EbuildBuild(pkg=pkg, register=self._register, |
163 |
+ schedule=self._schedule, settings=pkgsettings, |
164 |
+ unregister=self._unregister) |
165 |
retval = build.execute() |
166 |
if retval != os.EX_OK: |
167 |
raise self._pkg_failure(retval) |
168 |
|
169 |
-- |
170 |
gentoo-commits@l.g.o mailing list |