1 |
commit: 32e3bffa19329a848633a7fcefbf4fe3761dbfef |
2 |
Author: Zac Medico <zmedico <AT> gentoo <DOT> org> |
3 |
AuthorDate: Wed Feb 8 01:59:12 2012 +0000 |
4 |
Commit: Zac Medico <zmedico <AT> gentoo <DOT> org> |
5 |
CommitDate: Wed Feb 8 02:12:08 2012 +0000 |
6 |
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/portage.git;a=commit;h=32e3bffa |
7 |
|
8 |
PollScheduler: implement idle_add |
9 |
|
10 |
--- |
11 |
pym/_emerge/PollScheduler.py | 46 +++++++++++++++++++++++++++++++++++++++++- |
12 |
1 files changed, 45 insertions(+), 1 deletions(-) |
13 |
|
14 |
diff --git a/pym/_emerge/PollScheduler.py b/pym/_emerge/PollScheduler.py |
15 |
index 7cf8189..ab18f0d 100644 |
16 |
--- a/pym/_emerge/PollScheduler.py |
17 |
+++ b/pym/_emerge/PollScheduler.py |
18 |
@@ -24,9 +24,13 @@ from _emerge.PollSelectAdapter import PollSelectAdapter |
19 |
class PollScheduler(object): |
20 |
|
21 |
class _sched_iface_class(SlotObject): |
22 |
- __slots__ = ("io_add_watch", "output", "register", "schedule", |
23 |
+ __slots__ = ("idle_add", "io_add_watch", |
24 |
+ "output", "register", "schedule", |
25 |
"source_remove", "timeout_add", "unregister") |
26 |
|
27 |
+ class _idle_callback_class(SlotObject): |
28 |
+ __slots__ = ("args", "callback", "source_id") |
29 |
+ |
30 |
class _io_handler_class(SlotObject): |
31 |
__slots__ = ("args", "callback", "fd", "source_id") |
32 |
|
33 |
@@ -45,6 +49,7 @@ class PollScheduler(object): |
34 |
self._poll_event_handler_ids = {} |
35 |
# Increment id for each new handler. |
36 |
self._event_handler_id = 0 |
37 |
+ self._idle_callbacks = {} |
38 |
self._timeout_handlers = {} |
39 |
self._timeout_interval = None |
40 |
self._poll_obj = create_poll_instance() |
41 |
@@ -52,6 +57,7 @@ class PollScheduler(object): |
42 |
self._scheduling = False |
43 |
self._background = False |
44 |
self.sched_iface = self._sched_iface_class( |
45 |
+ idle_add=self._idle_add, |
46 |
io_add_watch=self._register, |
47 |
output=self._task_output, |
48 |
register=self._register, |
49 |
@@ -291,6 +297,35 @@ class PollScheduler(object): |
50 |
|
51 |
return bool(events_handled) |
52 |
|
53 |
+ def _idle_add(self, callback, *args): |
54 |
+ """ |
55 |
+ Like glib.idle_add(), if callback returns False it is |
56 |
+ automatically removed from the list of event sources and will |
57 |
+ not be called again. |
58 |
+ |
59 |
+ @type callback: callable |
60 |
+ @param callback: a function to call |
61 |
+ @rtype: int |
62 |
+ @return: an integer ID |
63 |
+ """ |
64 |
+ self._event_handler_id += 1 |
65 |
+ source_id = self._event_handler_id |
66 |
+ self._idle_callbacks[source_id] = self._idle_callback_class( |
67 |
+ args=args, callback=callback, source_id=source_id) |
68 |
+ return source_id |
69 |
+ |
70 |
+ def _run_idle_callbacks(self): |
71 |
+ if not self._idle_callbacks: |
72 |
+ return |
73 |
+ # Iterate of our local list, since self._idle_callbacks can be |
74 |
+ # modified during the exection of these callbacks. |
75 |
+ for x in list(self._idle_callbacks.values()): |
76 |
+ if x.source_id not in self._idle_callbacks: |
77 |
+ # it got cancelled while executing another callback |
78 |
+ continue |
79 |
+ if not x.callback(*x.args): |
80 |
+ self._unregister(x.source_id) |
81 |
+ |
82 |
def _timeout_add(self, interval, function, *args): |
83 |
""" |
84 |
Like glib.timeout_add(), interval argument is the number of |
85 |
@@ -317,6 +352,12 @@ class PollScheduler(object): |
86 |
return source_id |
87 |
|
88 |
def _run_timeouts(self): |
89 |
+ |
90 |
+ self._run_idle_callbacks() |
91 |
+ |
92 |
+ if not self._timeout_handlers: |
93 |
+ return False |
94 |
+ |
95 |
ready_timeouts = [] |
96 |
current_time = time.time() |
97 |
for x in self._timeout_handlers.values(): |
98 |
@@ -370,6 +411,9 @@ class PollScheduler(object): |
99 |
is found and removed, and False if the reg_id is invalid or has |
100 |
already been removed. |
101 |
""" |
102 |
+ idle_callback = self._idle_callbacks.pop(reg_id, None) |
103 |
+ if idle_callback is not None: |
104 |
+ return True |
105 |
timeout_handler = self._timeout_handlers.pop(reg_id, None) |
106 |
if timeout_handler is not None: |
107 |
if timeout_handler.interval == self._timeout_interval: |