Gentoo Archives: gentoo-commits

From: Zac Medico <zmedico@g.o>
To: gentoo-commits@l.g.o
Subject: [gentoo-commits] proj/portage:master commit in: pym/portage/dbapi/, pym/_emerge/
Date: Wed, 08 Feb 2012 01:16:40
Message-Id: 610831146c27d46256df45f127474d509c9a7d31.zmedico@gentoo
1 commit: 610831146c27d46256df45f127474d509c9a7d31
2 Author: Zac Medico <zmedico <AT> gentoo <DOT> org>
3 AuthorDate: Wed Feb 8 00:36:32 2012 +0000
4 Commit: Zac Medico <zmedico <AT> gentoo <DOT> org>
5 CommitDate: Wed Feb 8 01:15:47 2012 +0000
6 URL: http://git.overlays.gentoo.org/gitweb/?p=proj/portage.git;a=commit;h=61083114
7
8 PollScheduler: glib.io_add_watch() compatibility
9
10 ---
11 pym/_emerge/AsynchronousLock.py | 4 +++
12 pym/_emerge/EbuildIpcDaemon.py | 2 +
13 pym/_emerge/EbuildMetadataPhase.py | 2 +
14 pym/_emerge/PipeReader.py | 4 +++
15 pym/_emerge/PollScheduler.py | 50 ++++++++++++++++++++++++-----------
16 pym/_emerge/Scheduler.py | 1 +
17 pym/_emerge/SpawnProcess.py | 4 +++
18 pym/portage/dbapi/_MergeProcess.py | 2 +
19 8 files changed, 53 insertions(+), 16 deletions(-)
20
21 diff --git a/pym/_emerge/AsynchronousLock.py b/pym/_emerge/AsynchronousLock.py
22 index 3593834..e166df3 100644
23 --- a/pym/_emerge/AsynchronousLock.py
24 +++ b/pym/_emerge/AsynchronousLock.py
25 @@ -143,6 +143,8 @@ class _LockThread(AbstractPollTask):
26 self.returncode = os.EX_OK
27 self.wait()
28
29 + return True
30 +
31 def _cancel(self):
32 # There's currently no way to force thread termination.
33 pass
34 @@ -280,6 +282,8 @@ class _LockProcess(AbstractPollTask):
35 self.returncode = os.EX_OK
36 self.wait()
37
38 + return True
39 +
40 def _unregister(self):
41 self._registered = False
42
43
44 diff --git a/pym/_emerge/EbuildIpcDaemon.py b/pym/_emerge/EbuildIpcDaemon.py
45 index 5dabe34..6a320cb 100644
46 --- a/pym/_emerge/EbuildIpcDaemon.py
47 +++ b/pym/_emerge/EbuildIpcDaemon.py
48 @@ -84,6 +84,8 @@ class EbuildIpcDaemon(FifoIpcDaemon):
49 if reply_hook is not None:
50 reply_hook()
51
52 + return True
53 +
54 def _send_reply(self, reply):
55 # File streams are in unbuffered mode since we do atomic
56 # read and write of whole pickles. Use non-blocking mode so
57
58 diff --git a/pym/_emerge/EbuildMetadataPhase.py b/pym/_emerge/EbuildMetadataPhase.py
59 index d4f5bc0..f8da866 100644
60 --- a/pym/_emerge/EbuildMetadataPhase.py
61 +++ b/pym/_emerge/EbuildMetadataPhase.py
62 @@ -128,6 +128,8 @@ class EbuildMetadataPhase(SubProcess):
63
64 self._unregister_if_appropriate(event)
65
66 + return True
67 +
68 def _set_returncode(self, wait_retval):
69 SubProcess._set_returncode(self, wait_retval)
70 # self._raw_metadata is None when _start returns
71
72 diff --git a/pym/_emerge/PipeReader.py b/pym/_emerge/PipeReader.py
73 index 0f784cf..a85d794 100644
74 --- a/pym/_emerge/PipeReader.py
75 +++ b/pym/_emerge/PipeReader.py
76 @@ -74,6 +74,8 @@ class PipeReader(AbstractPollTask):
77
78 self._unregister_if_appropriate(event)
79
80 + return True
81 +
82 def _array_output_handler(self, fd, event):
83
84 for f in self.input_files.values():
85 @@ -93,6 +95,8 @@ class PipeReader(AbstractPollTask):
86
87 self._unregister_if_appropriate(event)
88
89 + return True
90 +
91 def _unregister(self):
92 """
93 Unregister from the scheduler and close open files.
94
95 diff --git a/pym/_emerge/PollScheduler.py b/pym/_emerge/PollScheduler.py
96 index 519a370..7cf8189 100644
97 --- a/pym/_emerge/PollScheduler.py
98 +++ b/pym/_emerge/PollScheduler.py
99 @@ -24,9 +24,12 @@ from _emerge.PollSelectAdapter import PollSelectAdapter
100 class PollScheduler(object):
101
102 class _sched_iface_class(SlotObject):
103 - __slots__ = ("output", "register", "schedule",
104 + __slots__ = ("io_add_watch", "output", "register", "schedule",
105 "source_remove", "timeout_add", "unregister")
106
107 + class _io_handler_class(SlotObject):
108 + __slots__ = ("args", "callback", "fd", "source_id")
109 +
110 class _timeout_handler_class(SlotObject):
111 __slots__ = ("args", "function", "interval", "source_id",
112 "timestamp")
113 @@ -49,6 +52,7 @@ class PollScheduler(object):
114 self._scheduling = False
115 self._background = False
116 self.sched_iface = self._sched_iface_class(
117 + io_add_watch=self._register,
118 output=self._task_output,
119 register=self._register,
120 schedule=self._schedule_wait,
121 @@ -248,8 +252,9 @@ class PollScheduler(object):
122 try:
123 while event_handlers:
124 f, event = self._next_poll_event()
125 - handler, reg_id = event_handlers[f]
126 - handler(f, event)
127 + x = event_handlers[f]
128 + if not x.callback(f, event, *x.args):
129 + self._unregister(x.source_id)
130 event_handled = True
131 except StopIteration:
132 event_handled = True
133 @@ -277,8 +282,9 @@ class PollScheduler(object):
134 try:
135 while event_handlers and self._poll_event_queue:
136 f, event = self._next_poll_event()
137 - handler, reg_id = event_handlers[f]
138 - handler(f, event)
139 + x = event_handlers[f]
140 + if not x.callback(f, event, *x.args):
141 + self._unregister(x.source_id)
142 events_handled += 1
143 except StopIteration:
144 events_handled += 1
145 @@ -332,20 +338,31 @@ class PollScheduler(object):
146
147 return bool(ready_timeouts)
148
149 - def _register(self, f, eventmask, handler):
150 + def _register(self, f, condition, callback, *args):
151 """
152 - @rtype: Integer
153 - @return: A unique registration id, for use in schedule() or
154 - unregister() calls.
155 + Like glib.io_add_watch(), your function should return False to
156 + stop being called, or True to continue being called. Any
157 + additional positional arguments given here are passed to your
158 + function when it's called.
159 +
160 + @type f: int or object with fileno() method
161 + @param f: a file descriptor to monitor
162 + @type condition: int
163 + @param condition: a condition mask
164 + @type callback: callable
165 + @param callback: a function to call
166 + @rtype: int
167 + @return: an integer ID of the event source
168 """
169 if f in self._poll_event_handlers:
170 raise AssertionError("fd %d is already registered" % f)
171 self._event_handler_id += 1
172 - reg_id = self._event_handler_id
173 - self._poll_event_handler_ids[reg_id] = f
174 - self._poll_event_handlers[f] = (handler, reg_id)
175 - self._poll_obj.register(f, eventmask)
176 - return reg_id
177 + source_id = self._event_handler_id
178 + self._poll_event_handler_ids[source_id] = f
179 + self._poll_event_handlers[f] = self._io_handler_class(
180 + args=args, callback=callback, f=f, source_id=source_id)
181 + self._poll_obj.register(f, condition)
182 + return source_id
183
184 def _unregister(self, reg_id):
185 """
186 @@ -409,8 +426,9 @@ class PollScheduler(object):
187 while (wait_ids is None and event_handlers) or \
188 (wait_ids is not None and wait_ids.intersection(handler_ids)):
189 f, event = self._next_poll_event(timeout=remaining_timeout)
190 - handler, reg_id = event_handlers[f]
191 - handler(f, event)
192 + x = event_handlers[f]
193 + if not x.callback(f, event, *x.args):
194 + self._unregister(x.source_id)
195 event_handled = True
196 if condition is not None and condition():
197 break
198
199 diff --git a/pym/_emerge/Scheduler.py b/pym/_emerge/Scheduler.py
200 index e6f3e0e..55e327f 100644
201 --- a/pym/_emerge/Scheduler.py
202 +++ b/pym/_emerge/Scheduler.py
203 @@ -218,6 +218,7 @@ class Scheduler(PollScheduler):
204 schedule=self._schedule_fetch)
205 self._sched_iface = self._iface_class(
206 fetch=fetch_iface, output=self._task_output,
207 + io_add_watch=self._register,
208 register=self._register,
209 schedule=self._schedule_wait,
210 scheduleSetup=self._schedule_setup,
211
212 diff --git a/pym/_emerge/SpawnProcess.py b/pym/_emerge/SpawnProcess.py
213 index ec5bf7d..411e7c6 100644
214 --- a/pym/_emerge/SpawnProcess.py
215 +++ b/pym/_emerge/SpawnProcess.py
216 @@ -218,6 +218,8 @@ class SpawnProcess(SubProcess):
217
218 self._unregister_if_appropriate(event)
219
220 + return True
221 +
222 def _dummy_handler(self, fd, event):
223 """
224 This method is mainly interested in detecting EOF, since
225 @@ -240,6 +242,8 @@ class SpawnProcess(SubProcess):
226
227 self._unregister_if_appropriate(event)
228
229 + return True
230 +
231 def _unregister(self):
232 super(SpawnProcess, self)._unregister()
233 if self._log_file_real is not None:
234
235 diff --git a/pym/portage/dbapi/_MergeProcess.py b/pym/portage/dbapi/_MergeProcess.py
236 index df501be..eed7bd4 100644
237 --- a/pym/portage/dbapi/_MergeProcess.py
238 +++ b/pym/portage/dbapi/_MergeProcess.py
239 @@ -83,6 +83,8 @@ class MergeProcess(SpawnProcess):
240 reporter = getattr(portage.elog.messages, funcname)
241 reporter(msg, phase=phase, key=key, out=out)
242
243 + return True
244 +
245 def _spawn(self, args, fd_pipes, **kwargs):
246 """
247 Fork a subprocess, apply local settings, and call