1 |
Author: zmedico |
2 |
Date: 2008-07-04 06:15:43 +0000 (Fri, 04 Jul 2008) |
3 |
New Revision: 10921 |
4 |
|
5 |
Modified: |
6 |
main/trunk/pym/_emerge/__init__.py |
7 |
Log: |
8 |
Change the way the way things that have to call the scheduler interact |
9 |
with it: |
10 |
|
11 |
* Return a unique integer id from scheduler.register(), to be passed back |
12 |
into other scheduler methods. |
13 |
|
14 |
* Control handler unregistration with the handler's return value, like |
15 |
some other frameworks do for similar callbacks. |
16 |
|
17 |
* Add a SpawnProcess.reg_id attribute to store the id returned from |
18 |
scheduler.register() |
19 |
|
20 |
* Pass the SpawnProcess.reg_id value into scheduler.schedule() calls, |
21 |
so the scheduler knows to return when the callback referred to by |
22 |
the given id unregisters itself by returning False. |
23 |
|
24 |
|
25 |
|
26 |
Modified: main/trunk/pym/_emerge/__init__.py |
27 |
=================================================================== |
28 |
--- main/trunk/pym/_emerge/__init__.py 2008-07-04 03:03:44 UTC (rev 10920) |
29 |
+++ main/trunk/pym/_emerge/__init__.py 2008-07-04 06:15:43 UTC (rev 10921) |
30 |
@@ -1507,7 +1507,7 @@ |
31 |
"uid", "gid", "groups", "umask", "logfile", |
32 |
"path_lookup", "pre_exec") |
33 |
|
34 |
- __slots__ = ("args", "files", "register", "unregister", "registered") + \ |
35 |
+ __slots__ = ("args", "files", "registered", "reg_id", "scheduler") + \ |
36 |
_spawn_kwarg_names |
37 |
|
38 |
_file_names = ("process", "out") |
39 |
@@ -1573,9 +1573,9 @@ |
40 |
|
41 |
os.close(slave_fd) |
42 |
files.process = os.fdopen(master_fd, 'r') |
43 |
+ self.reg_id = self.scheduler.register(files.process.fileno(), |
44 |
+ select.POLLIN, self._output_handler) |
45 |
self.registered = True |
46 |
- self.register(files.process.fileno(), |
47 |
- select.POLLIN, self._output_handler) |
48 |
|
49 |
def _output_handler(self, fd, event): |
50 |
files = self.files |
51 |
@@ -1593,7 +1593,7 @@ |
52 |
f.flush() |
53 |
f.close() |
54 |
self.registered = False |
55 |
- self.unregister(fd) |
56 |
+ return self.registered |
57 |
|
58 |
class EbuildFetcherAsync(SpawnProcess): |
59 |
|
60 |
@@ -1766,9 +1766,8 @@ |
61 |
(pkg_count.curval, pkg_count.maxval, pkg.cpv) |
62 |
logger.log(msg, short_msg=short_msg) |
63 |
|
64 |
- build = EbuildExecuter(pkg=pkg, register=scheduler.register, |
65 |
- schedule=scheduler.schedule, settings=settings, |
66 |
- unregister=scheduler.unregister) |
67 |
+ build = EbuildExecuter(pkg=pkg, scheduler=scheduler, |
68 |
+ settings=settings) |
69 |
retval = build.execute() |
70 |
if retval != os.EX_OK: |
71 |
return retval |
72 |
@@ -1804,9 +1803,8 @@ |
73 |
(pkg_count.curval, pkg_count.curval, pkg.cpv) |
74 |
logger.log(msg, short_msg=short_msg) |
75 |
|
76 |
- build = EbuildExecuter(pkg=pkg, register=scheduler.register, |
77 |
- schedule=scheduler.schedule, settings=settings, |
78 |
- unregister=scheduler.unregister) |
79 |
+ build = EbuildExecuter(pkg=pkg, scheduler=scheduler, |
80 |
+ settings=settings) |
81 |
retval = build.execute() |
82 |
if retval != os.EX_OK: |
83 |
return retval |
84 |
@@ -1827,7 +1825,7 @@ |
85 |
|
86 |
class EbuildExecuter(SlotObject): |
87 |
|
88 |
- __slots__ = ("pkg", "register", "schedule", "settings", "unregister") |
89 |
+ __slots__ = ("pkg", "scheduler", "settings") |
90 |
|
91 |
_phases = ("setup", "unpack", "compile", "test", "install") |
92 |
|
93 |
@@ -1857,14 +1855,12 @@ |
94 |
|
95 |
for mydo in self._phases: |
96 |
ebuild_phase = EbuildPhase(fd_pipes=fd_pipes, |
97 |
- pkg=self.pkg, phase=mydo, register=self.register, |
98 |
- settings=settings, tree=tree, unregister=self.unregister) |
99 |
+ pkg=self.pkg, phase=mydo, scheduler=self.scheduler, |
100 |
+ settings=settings, tree=tree) |
101 |
|
102 |
ebuild_phase.start() |
103 |
- retval = None |
104 |
- while retval is None: |
105 |
- self.schedule() |
106 |
- retval = ebuild_phase.poll() |
107 |
+ self.scheduler.schedule(ebuild_phase.reg_id) |
108 |
+ retval = ebuild_phase.wait() |
109 |
|
110 |
if retval != os.EX_OK: |
111 |
return retval |
112 |
@@ -1874,8 +1870,8 @@ |
113 |
class EbuildPhase(SubProcess): |
114 |
|
115 |
__slots__ = ("fd_pipes", "phase", "pkg", |
116 |
- "register", "settings", "tree", "unregister", |
117 |
- "files", "registered") |
118 |
+ "scheduler", "settings", "tree", |
119 |
+ "files", "registered", "reg_id") |
120 |
|
121 |
_file_names = ("log", "stdout", "ebuild") |
122 |
_files_dict = slot_dict_class(_file_names, prefix="") |
123 |
@@ -1976,8 +1972,9 @@ |
124 |
|
125 |
os.close(slave_fd) |
126 |
files.ebuild = os.fdopen(master_fd, 'r') |
127 |
+ self.reg_id = self.scheduler.register(files.ebuild.fileno(), |
128 |
+ select.POLLIN, output_handler) |
129 |
self.registered = True |
130 |
- self.register(files.ebuild.fileno(), select.POLLIN, output_handler) |
131 |
|
132 |
def _output_handler(self, fd, event): |
133 |
files = self.files |
134 |
@@ -1996,7 +1993,7 @@ |
135 |
for f in files.values(): |
136 |
f.close() |
137 |
self.registered = False |
138 |
- self.unregister(fd) |
139 |
+ return self.registered |
140 |
|
141 |
def _dummy_handler(self, fd, event): |
142 |
""" |
143 |
@@ -2017,7 +2014,7 @@ |
144 |
for f in files.values(): |
145 |
f.close() |
146 |
self.registered = False |
147 |
- self.unregister(fd) |
148 |
+ return self.registered |
149 |
|
150 |
def _set_returncode(self, wait_retval): |
151 |
SubProcess._set_returncode(self, wait_retval) |
152 |
@@ -2195,9 +2192,8 @@ |
153 |
for line in wrap(waiting_msg, 65)) |
154 |
writemsg(waiting_msg, noiselevel=-1) |
155 |
|
156 |
- while retval is None: |
157 |
- scheduler.schedule() |
158 |
- retval = prefetcher.poll() |
159 |
+ scheduler.schedule(prefetcher.reg_id) |
160 |
+ retval = prefetcher.wait() |
161 |
del prefetcher |
162 |
|
163 |
fetcher = BinpkgFetcher(pkg=pkg, pretend=opts.pretend, |
164 |
@@ -2306,27 +2302,22 @@ |
165 |
|
166 |
phase = "setup" |
167 |
ebuild_phase = EbuildPhase(fd_pipes=fd_pipes, |
168 |
- pkg=pkg, phase=phase, register=scheduler.register, |
169 |
- settings=settings, tree=tree, unregister=scheduler.unregister) |
170 |
+ pkg=pkg, phase=phase, scheduler=scheduler, |
171 |
+ settings=settings, tree=tree) |
172 |
|
173 |
ebuild_phase.start() |
174 |
- retval = None |
175 |
- while retval is None: |
176 |
- scheduler.schedule() |
177 |
- retval = ebuild_phase.poll() |
178 |
+ scheduler.schedule(ebuild_phase.reg_id) |
179 |
+ retval = ebuild_phase.wait() |
180 |
|
181 |
if retval != os.EX_OK: |
182 |
return retval |
183 |
|
184 |
extractor = BinpkgExtractorAsync(image_dir=image_dir, |
185 |
- pkg=pkg, pkg_path=pkg_path, register=scheduler.register, |
186 |
- unregister=scheduler.unregister) |
187 |
+ pkg=pkg, pkg_path=pkg_path, scheduler=scheduler) |
188 |
portage.writemsg_stdout(">>> Extracting %s\n" % pkg.cpv) |
189 |
extractor.start() |
190 |
- retval = None |
191 |
- while retval is None: |
192 |
- scheduler.schedule() |
193 |
- retval = extractor.poll() |
194 |
+ scheduler.schedule(extractor.reg_id) |
195 |
+ retval = extractor.wait() |
196 |
|
197 |
if retval != os.EX_OK: |
198 |
writemsg("!!! Error Extracting '%s'\n" % pkg_path, |
199 |
@@ -7061,7 +7052,7 @@ |
200 |
_fetch_log = "/var/log/emerge-fetch.log" |
201 |
|
202 |
class _iface_class(SlotObject): |
203 |
- __slots__ = ("register", "schedule", "unregister") |
204 |
+ __slots__ = ("register", "schedule") |
205 |
|
206 |
class _build_opts_class(SlotObject): |
207 |
__slots__ = ("buildpkg", "buildpkgonly", |
208 |
@@ -7111,9 +7102,11 @@ |
209 |
self._logger = self._emerge_log_class( |
210 |
xterm_titles=("notitles" not in settings.features)) |
211 |
self._sched_iface = self._iface_class( |
212 |
- register=self._register, schedule=self._schedule, |
213 |
- unregister=self._unregister) |
214 |
+ register=self._register, schedule=self._schedule) |
215 |
self._poll_event_handlers = {} |
216 |
+ self._poll_event_handler_ids = {} |
217 |
+ # Increment id for each new handler. |
218 |
+ self._event_handler_id = 0 |
219 |
|
220 |
try: |
221 |
self._poll = select.poll() |
222 |
@@ -7264,14 +7257,14 @@ |
223 |
elif pkg.type_name == "ebuild": |
224 |
|
225 |
prefetcher = EbuildFetcherAsync(logfile=self._fetch_log, pkg=pkg, |
226 |
- register=self._register, unregister=self._unregister) |
227 |
+ scheduler=self._sched_iface) |
228 |
|
229 |
elif pkg.type_name == "binary" and \ |
230 |
"--getbinpkg" in self.myopts and \ |
231 |
pkg.root_config.trees["bintree"].isremote(pkg.cpv): |
232 |
|
233 |
prefetcher = BinpkgFetcherAsync(logfile=self._fetch_log, |
234 |
- pkg=pkg, register=self._register, unregister=self._unregister) |
235 |
+ pkg=pkg, scheduler=self._sched_iface) |
236 |
|
237 |
return prefetcher |
238 |
|
239 |
@@ -7476,31 +7469,44 @@ |
240 |
return (mylist, dropped_tasks) |
241 |
|
242 |
def _register(self, f, eventmask, handler): |
243 |
- self._poll_event_handlers[f] = handler |
244 |
+ """ |
245 |
+ @rtype: Integer |
246 |
+ @return: A unique registration id, for use in schedule() or |
247 |
+ unregister() calls. |
248 |
+ """ |
249 |
+ self._event_handler_id += 1 |
250 |
+ reg_id = self._event_handler_id |
251 |
+ self._poll_event_handler_ids[reg_id] = f |
252 |
+ self._poll_event_handlers[f] = (handler, reg_id) |
253 |
self._poll.register(f, eventmask) |
254 |
+ return reg_id |
255 |
|
256 |
- def _unregister(self, f): |
257 |
+ def _unregister(self, reg_id): |
258 |
+ f = self._poll_event_handler_ids[reg_id] |
259 |
self._poll.unregister(f) |
260 |
del self._poll_event_handlers[f] |
261 |
+ del self._poll_event_handler_ids[reg_id] |
262 |
self._schedule_tasks() |
263 |
|
264 |
- def _schedule(self): |
265 |
+ def _schedule(self, wait_id): |
266 |
+ """ |
267 |
+ Schedule until wait_id is not longer registered |
268 |
+ for poll() events. |
269 |
+ @type wait_id: int |
270 |
+ @param wait_id: a task id to wait for |
271 |
+ """ |
272 |
event_handlers = self._poll_event_handlers |
273 |
- running_tasks = self._prefetch_queue.running_tasks |
274 |
+ handler_ids = self._poll_event_handler_ids |
275 |
poll = self._poll.poll |
276 |
|
277 |
self._schedule_tasks() |
278 |
|
279 |
- while event_handlers: |
280 |
+ while wait_id in handler_ids: |
281 |
for f, event in poll(): |
282 |
- event_handlers[f](f, event) |
283 |
+ handler, reg_id = event_handlers[f] |
284 |
+ if not handler(f, event): |
285 |
+ self._unregister(reg_id) |
286 |
|
287 |
- if len(event_handlers) <= len(running_tasks): |
288 |
- # Assuming one handler per task, this |
289 |
- # means the caller has unregistered it's |
290 |
- # handler, so it's time to yield. |
291 |
- break |
292 |
- |
293 |
def _world_atom(self, pkg): |
294 |
""" |
295 |
Add the package to the world file, but only if |
296 |
@@ -7565,8 +7571,6 @@ |
297 |
self._logger.log(" >>> emerge (%s of %s) %s to %s" % \ |
298 |
(pkg_count.curval, pkg_count.maxval, pkg.cpv, pkg.root)) |
299 |
|
300 |
- self._schedule() |
301 |
- |
302 |
if pkg.type_name == "ebuild": |
303 |
build = EbuildBuild(args_set=self._args_set, |
304 |
find_blockers=self._find_blockers(pkg), |
305 |
|
306 |
-- |
307 |
gentoo-commits@l.g.o mailing list |