summaryrefslogtreecommitdiffstats
path: root/bitbake/lib/bb/event.py
diff options
context:
space:
mode:
Diffstat (limited to 'bitbake/lib/bb/event.py')
-rw-r--r--bitbake/lib/bb/event.py211
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
25import os, re 25import os, re
26import bb.utils 26import bb.utils
27import pickle
28
29# This is the pid for which we should generate the event. This is set when
30# the runqueue forks off.
31worker_pid = 0
32worker_pipe = None
27 33
28class Event: 34class 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
43NotHandled = 0 40NotHandled = 0
44Handled = 1 41Handled = 1
@@ -47,75 +44,83 @@ Registered = 10
47AlreadyRegistered = 14 44AlreadyRegistered = 14
48 45
49# Internal 46# Internal
50_handlers = [] 47_handlers = {}
51_handlers_dict = {} 48_ui_handlers = {}
49_ui_handler_seq = 0
52 50
53def tmpHandler(event): 51def fire(event, d):
54 """Default handler for code events""" 52 """Fire off an Event"""
55 return NotHandled
56 53
57def 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
62def 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
81def 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
86def 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
74def register(name, handler): 93def 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
91def _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
104def remove(name, handler): 111def remove(name, handler):
105 """Remove an Event handler""" 112 """Remove an Event handler"""
113 _handlers.pop(name)
106 114
107 _handlers_dict.pop(name) 115def 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
113def _removeCode(handlerStr): 120def 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
120def getName(e): 125def 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):
130class RecipeParsed(Event): 135class 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
137class StampUpdate(Event): 142class 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
154class 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
170class BuildBase(Event): 159class 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
208class 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
224class PkgStarted(PkgBase):
225 """Package build started"""
226 197
227 198
228class PkgFailed(PkgBase):
229 """Package build failed"""
230
231
232class PkgSucceeded(PkgBase):
233 """Package build completed"""
234
235 199
236class BuildStarted(BuildBase): 200class 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
244class UnsatisfiedDep(DepBase):
245 """Unsatisfied Dependency"""
246 208
247 209
248class RecursiveDep(DepBase):
249 """Recursive Dependency"""
250
251class NoProvider(Event): 210class 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):
265class MultipleProviders(Event): 224class 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
251class 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
267class 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