diff options
Diffstat (limited to 'bitbake/lib/bb/event.py')
-rw-r--r-- | bitbake/lib/bb/event.py | 211 |
1 files changed, 98 insertions, 113 deletions
diff --git a/bitbake/lib/bb/event.py b/bitbake/lib/bb/event.py index 9d7341f878..7251d78715 100644 --- a/bitbake/lib/bb/event.py +++ b/bitbake/lib/bb/event.py | |||
@@ -24,21 +24,18 @@ BitBake build tools. | |||
24 | 24 | ||
25 | import os, re | 25 | import os, re |
26 | import bb.utils | 26 | import bb.utils |
27 | import pickle | ||
28 | |||
29 | # This is the pid for which we should generate the event. This is set when | ||
30 | # the runqueue forks off. | ||
31 | worker_pid = 0 | ||
32 | worker_pipe = None | ||
27 | 33 | ||
28 | class Event: | 34 | class Event: |
29 | """Base class for events""" | 35 | """Base class for events""" |
30 | type = "Event" | ||
31 | |||
32 | def __init__(self, d): | ||
33 | self._data = d | ||
34 | |||
35 | def getData(self): | ||
36 | return self._data | ||
37 | |||
38 | def setData(self, data): | ||
39 | self._data = data | ||
40 | 36 | ||
41 | data = property(getData, setData, None, "data property") | 37 | def __init__(self): |
38 | self.pid = worker_pid | ||
42 | 39 | ||
43 | NotHandled = 0 | 40 | NotHandled = 0 |
44 | Handled = 1 | 41 | Handled = 1 |
@@ -47,75 +44,83 @@ Registered = 10 | |||
47 | AlreadyRegistered = 14 | 44 | AlreadyRegistered = 14 |
48 | 45 | ||
49 | # Internal | 46 | # Internal |
50 | _handlers = [] | 47 | _handlers = {} |
51 | _handlers_dict = {} | 48 | _ui_handlers = {} |
49 | _ui_handler_seq = 0 | ||
52 | 50 | ||
53 | def tmpHandler(event): | 51 | def fire(event, d): |
54 | """Default handler for code events""" | 52 | """Fire off an Event""" |
55 | return NotHandled | ||
56 | 53 | ||
57 | def defaultTmpHandler(): | 54 | if worker_pid != 0: |
58 | tmp = "def tmpHandler(e):\n\t\"\"\"heh\"\"\"\n\treturn NotHandled" | 55 | worker_fire(event, d) |
59 | comp = bb.utils.better_compile(tmp, "tmpHandler(e)", "bb.event.defaultTmpHandler") | 56 | return |
60 | return comp | ||
61 | 57 | ||
62 | def fire(event): | 58 | for handler in _handlers: |
63 | """Fire off an Event""" | 59 | h = _handlers[handler] |
64 | for h in _handlers: | 60 | event.data = d |
65 | if type(h).__name__ == "code": | 61 | if type(h).__name__ == "code": |
66 | exec(h) | 62 | exec(h) |
67 | if tmpHandler(event) == Handled: | 63 | tmpHandler(event) |
68 | return Handled | ||
69 | else: | 64 | else: |
70 | if h(event) == Handled: | 65 | h(event) |
71 | return Handled | 66 | del event.data |
72 | return NotHandled | 67 | |
68 | errors = [] | ||
69 | for h in _ui_handlers: | ||
70 | #print "Sending event %s" % event | ||
71 | try: | ||
72 | # We use pickle here since it better handles object instances | ||
73 | # which xmlrpc's marshaller does not. Events *must* be serializable | ||
74 | # by pickle. | ||
75 | _ui_handlers[h].event.send((pickle.dumps(event))) | ||
76 | except: | ||
77 | errors.append(h) | ||
78 | for h in errors: | ||
79 | del _ui_handlers[h] | ||
80 | |||
81 | def worker_fire(event, d): | ||
82 | data = "<event>" + pickle.dumps(event) + "</event>" | ||
83 | if os.write(worker_pipe, data) != len (data): | ||
84 | print "Error sending event to server (short write)" | ||
85 | |||
86 | def fire_from_worker(event, d): | ||
87 | if not event.startswith("<event>") or not event.endswith("</event>"): | ||
88 | print "Error, not an event" | ||
89 | return | ||
90 | event = pickle.loads(event[7:-8]) | ||
91 | bb.event.fire(event, d) | ||
73 | 92 | ||
74 | def register(name, handler): | 93 | def register(name, handler): |
75 | """Register an Event handler""" | 94 | """Register an Event handler""" |
76 | 95 | ||
77 | # already registered | 96 | # already registered |
78 | if name in _handlers_dict: | 97 | if name in _handlers: |
79 | return AlreadyRegistered | 98 | return AlreadyRegistered |
80 | 99 | ||
81 | if handler is not None: | 100 | if handler is not None: |
82 | # handle string containing python code | 101 | # handle string containing python code |
83 | if type(handler).__name__ == "str": | 102 | if type(handler).__name__ == "str": |
84 | _registerCode(handler) | 103 | tmp = "def tmpHandler(e):\n%s" % handler |
104 | comp = bb.utils.better_compile(tmp, "tmpHandler(e)", "bb.event._registerCode") | ||
105 | _handlers[name] = comp | ||
85 | else: | 106 | else: |
86 | _handlers.append(handler) | 107 | _handlers[name] = handler |
87 | 108 | ||
88 | _handlers_dict[name] = 1 | ||
89 | return Registered | 109 | return Registered |
90 | 110 | ||
91 | def _registerCode(handlerStr): | ||
92 | """Register a 'code' Event. | ||
93 | Deprecated interface; call register instead. | ||
94 | |||
95 | Expects to be passed python code as a string, which will | ||
96 | be passed in turn to compile() and then exec(). Note that | ||
97 | the code will be within a function, so should have had | ||
98 | appropriate tabbing put in place.""" | ||
99 | tmp = "def tmpHandler(e):\n%s" % handlerStr | ||
100 | comp = bb.utils.better_compile(tmp, "tmpHandler(e)", "bb.event._registerCode") | ||
101 | # prevent duplicate registration | ||
102 | _handlers.append(comp) | ||
103 | |||
104 | def remove(name, handler): | 111 | def remove(name, handler): |
105 | """Remove an Event handler""" | 112 | """Remove an Event handler""" |
113 | _handlers.pop(name) | ||
106 | 114 | ||
107 | _handlers_dict.pop(name) | 115 | def register_UIHhandler(handler): |
108 | if type(handler).__name__ == "str": | 116 | bb.event._ui_handler_seq = bb.event._ui_handler_seq + 1 |
109 | return _removeCode(handler) | 117 | _ui_handlers[_ui_handler_seq] = handler |
110 | else: | 118 | return _ui_handler_seq |
111 | _handlers.remove(handler) | ||
112 | 119 | ||
113 | def _removeCode(handlerStr): | 120 | def unregister_UIHhandler(handlerNum): |
114 | """Remove a 'code' Event handler | 121 | if handlerNum in _ui_handlers: |
115 | Deprecated interface; call remove instead.""" | 122 | del _ui_handlers[handlerNum] |
116 | tmp = "def tmpHandler(e):\n%s" % handlerStr | 123 | return |
117 | comp = bb.utils.better_compile(tmp, "tmpHandler(e)", "bb.event._removeCode") | ||
118 | _handlers.remove(comp) | ||
119 | 124 | ||
120 | def getName(e): | 125 | def getName(e): |
121 | """Returns the name of a class or class instance""" | 126 | """Returns the name of a class or class instance""" |
@@ -130,17 +135,17 @@ class ConfigParsed(Event): | |||
130 | class RecipeParsed(Event): | 135 | class RecipeParsed(Event): |
131 | """ Recipe Parsing Complete """ | 136 | """ Recipe Parsing Complete """ |
132 | 137 | ||
133 | def __init__(self, fn, d): | 138 | def __init__(self, fn): |
134 | self.fn = fn | 139 | self.fn = fn |
135 | Event.__init__(self, d) | 140 | Event.__init__(self) |
136 | 141 | ||
137 | class StampUpdate(Event): | 142 | class StampUpdate(Event): |
138 | """Trigger for any adjustment of the stamp files to happen""" | 143 | """Trigger for any adjustment of the stamp files to happen""" |
139 | 144 | ||
140 | def __init__(self, targets, stampfns, d): | 145 | def __init__(self, targets, stampfns): |
141 | self._targets = targets | 146 | self._targets = targets |
142 | self._stampfns = stampfns | 147 | self._stampfns = stampfns |
143 | Event.__init__(self, d) | 148 | Event.__init__(self) |
144 | 149 | ||
145 | def getStampPrefix(self): | 150 | def getStampPrefix(self): |
146 | return self._stampfns | 151 | return self._stampfns |
@@ -151,29 +156,13 @@ class StampUpdate(Event): | |||
151 | stampPrefix = property(getStampPrefix) | 156 | stampPrefix = property(getStampPrefix) |
152 | targets = property(getTargets) | 157 | targets = property(getTargets) |
153 | 158 | ||
154 | class PkgBase(Event): | ||
155 | """Base class for package events""" | ||
156 | |||
157 | def __init__(self, t, d): | ||
158 | self._pkg = t | ||
159 | Event.__init__(self, d) | ||
160 | |||
161 | def getPkg(self): | ||
162 | return self._pkg | ||
163 | |||
164 | def setPkg(self, pkg): | ||
165 | self._pkg = pkg | ||
166 | |||
167 | pkg = property(getPkg, setPkg, None, "pkg property") | ||
168 | |||
169 | |||
170 | class BuildBase(Event): | 159 | class BuildBase(Event): |
171 | """Base class for bbmake run events""" | 160 | """Base class for bbmake run events""" |
172 | 161 | ||
173 | def __init__(self, n, p, c, failures = 0): | 162 | def __init__(self, n, p, failures = 0): |
174 | self._name = n | 163 | self._name = n |
175 | self._pkgs = p | 164 | self._pkgs = p |
176 | Event.__init__(self, c) | 165 | Event.__init__(self) |
177 | self._failures = failures | 166 | self._failures = failures |
178 | 167 | ||
179 | def getPkgs(self): | 168 | def getPkgs(self): |
@@ -205,33 +194,8 @@ class BuildBase(Event): | |||
205 | cfg = property(getCfg, setCfg, None, "cfg property") | 194 | cfg = property(getCfg, setCfg, None, "cfg property") |
206 | 195 | ||
207 | 196 | ||
208 | class DepBase(PkgBase): | ||
209 | """Base class for dependency events""" | ||
210 | |||
211 | def __init__(self, t, data, d): | ||
212 | self._dep = d | ||
213 | PkgBase.__init__(self, t, data) | ||
214 | |||
215 | def getDep(self): | ||
216 | return self._dep | ||
217 | |||
218 | def setDep(self, dep): | ||
219 | self._dep = dep | ||
220 | |||
221 | dep = property(getDep, setDep, None, "dep property") | ||
222 | |||
223 | |||
224 | class PkgStarted(PkgBase): | ||
225 | """Package build started""" | ||
226 | 197 | ||
227 | 198 | ||
228 | class PkgFailed(PkgBase): | ||
229 | """Package build failed""" | ||
230 | |||
231 | |||
232 | class PkgSucceeded(PkgBase): | ||
233 | """Package build completed""" | ||
234 | |||
235 | 199 | ||
236 | class BuildStarted(BuildBase): | 200 | class BuildStarted(BuildBase): |
237 | """bbmake build run started""" | 201 | """bbmake build run started""" |
@@ -241,18 +205,13 @@ class BuildCompleted(BuildBase): | |||
241 | """bbmake build run completed""" | 205 | """bbmake build run completed""" |
242 | 206 | ||
243 | 207 | ||
244 | class UnsatisfiedDep(DepBase): | ||
245 | """Unsatisfied Dependency""" | ||
246 | 208 | ||
247 | 209 | ||
248 | class RecursiveDep(DepBase): | ||
249 | """Recursive Dependency""" | ||
250 | |||
251 | class NoProvider(Event): | 210 | class NoProvider(Event): |
252 | """No Provider for an Event""" | 211 | """No Provider for an Event""" |
253 | 212 | ||
254 | def __init__(self, item, data,runtime=False): | 213 | def __init__(self, item, runtime=False): |
255 | Event.__init__(self, data) | 214 | Event.__init__(self) |
256 | self._item = item | 215 | self._item = item |
257 | self._runtime = runtime | 216 | self._runtime = runtime |
258 | 217 | ||
@@ -265,8 +224,8 @@ class NoProvider(Event): | |||
265 | class MultipleProviders(Event): | 224 | class MultipleProviders(Event): |
266 | """Multiple Providers""" | 225 | """Multiple Providers""" |
267 | 226 | ||
268 | def __init__(self, item, candidates, data, runtime = False): | 227 | def __init__(self, item, candidates, runtime = False): |
269 | Event.__init__(self, data) | 228 | Event.__init__(self) |
270 | self._item = item | 229 | self._item = item |
271 | self._candidates = candidates | 230 | self._candidates = candidates |
272 | self._is_runtime = runtime | 231 | self._is_runtime = runtime |
@@ -288,3 +247,29 @@ class MultipleProviders(Event): | |||
288 | Get the possible Candidates for a PROVIDER. | 247 | Get the possible Candidates for a PROVIDER. |
289 | """ | 248 | """ |
290 | return self._candidates | 249 | return self._candidates |
250 | |||
251 | class ParseProgress(Event): | ||
252 | """ | ||
253 | Parsing Progress Event | ||
254 | """ | ||
255 | |||
256 | def __init__(self, cached, parsed, skipped, masked, virtuals, errors, total): | ||
257 | Event.__init__(self) | ||
258 | self.cached = cached | ||
259 | self.parsed = parsed | ||
260 | self.skipped = skipped | ||
261 | self.virtuals = virtuals | ||
262 | self.masked = masked | ||
263 | self.errors = errors | ||
264 | self.sofar = cached + parsed | ||
265 | self.total = total | ||
266 | |||
267 | class DepTreeGenerated(Event): | ||
268 | """ | ||
269 | Event when a dependency tree has been generated | ||
270 | """ | ||
271 | |||
272 | def __init__(self, depgraph): | ||
273 | Event.__init__(self) | ||
274 | self._depgraph = depgraph | ||
275 | |||