summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRichard Purdie <richard.purdie@linuxfoundation.org>2022-12-20 14:20:22 +0000
committerRichard Purdie <richard.purdie@linuxfoundation.org>2022-12-29 00:07:06 +0000
commit907e91796ed4156cafcbd3ee60edaa9544f0abe3 (patch)
tree29c6a113f4b38ce6426ea41d0a035df45e206792
parent6549f58cd6e22b4c345212237e81e68e12dfcb61 (diff)
downloadpoky-907e91796ed4156cafcbd3ee60edaa9544f0abe3.tar.gz
bitbake: event: builtins fix for 'd' deletion
I've been seeing event handlers where 'd' seems to disappear half way through event handler execution. This is problematic when multiple threads are active since this code assumes single threading. The easiest fix is to change the handler function calls to contain d as a parameter as we do elsewhere for other functions. This will break any non-text handlers but I was only able to spot one of those in runqueue. It will also break handlers than call functions that assume 'd' is in the global namespace but those failures should be obvious and we can fix those to pass d around. This solution avoids manipulating builtins which was always a horrible thing to do anyway and solves the issue without needing locking, thankfully. (Bitbake rev: 1e12f0a4b592dacd006d370ec29cd71d2a44312e) Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
-rw-r--r--bitbake/lib/bb/event.py18
-rw-r--r--bitbake/lib/bb/runqueue.py2
-rw-r--r--bitbake/lib/bb/tests/color.py2
-rw-r--r--bitbake/lib/bb/tests/event.py21
4 files changed, 17 insertions, 26 deletions
diff --git a/bitbake/lib/bb/event.py b/bitbake/lib/bb/event.py
index 97668601a1..303b7a943f 100644
--- a/bitbake/lib/bb/event.py
+++ b/bitbake/lib/bb/event.py
@@ -70,11 +70,6 @@ _uiready = False
70_thread_lock = threading.Lock() 70_thread_lock = threading.Lock()
71_thread_lock_enabled = False 71_thread_lock_enabled = False
72 72
73if hasattr(__builtins__, '__setitem__'):
74 builtins = __builtins__
75else:
76 builtins = __builtins__.__dict__
77
78def enable_threadlock(): 73def enable_threadlock():
79 global _thread_lock_enabled 74 global _thread_lock_enabled
80 _thread_lock_enabled = True 75 _thread_lock_enabled = True
@@ -85,12 +80,8 @@ def disable_threadlock():
85 80
86def execute_handler(name, handler, event, d): 81def execute_handler(name, handler, event, d):
87 event.data = d 82 event.data = d
88 addedd = False
89 if 'd' not in builtins:
90 builtins['d'] = d
91 addedd = True
92 try: 83 try:
93 ret = handler(event) 84 ret = handler(event, d)
94 except (bb.parse.SkipRecipe, bb.BBHandledException): 85 except (bb.parse.SkipRecipe, bb.BBHandledException):
95 raise 86 raise
96 except Exception: 87 except Exception:
@@ -104,8 +95,7 @@ def execute_handler(name, handler, event, d):
104 raise 95 raise
105 finally: 96 finally:
106 del event.data 97 del event.data
107 if addedd: 98
108 del builtins['d']
109 99
110def fire_class_handlers(event, d): 100def fire_class_handlers(event, d):
111 if isinstance(event, logging.LogRecord): 101 if isinstance(event, logging.LogRecord):
@@ -253,12 +243,12 @@ def register(name, handler, mask=None, filename=None, lineno=None, data=None):
253 if handler is not None: 243 if handler is not None:
254 # handle string containing python code 244 # handle string containing python code
255 if isinstance(handler, str): 245 if isinstance(handler, str):
256 tmp = "def %s(e):\n%s" % (name, handler) 246 tmp = "def %s(e, d):\n%s" % (name, handler)
257 try: 247 try:
258 code = bb.methodpool.compile_cache(tmp) 248 code = bb.methodpool.compile_cache(tmp)
259 if not code: 249 if not code:
260 if filename is None: 250 if filename is None:
261 filename = "%s(e)" % name 251 filename = "%s(e, d)" % name
262 code = compile(tmp, filename, "exec", ast.PyCF_ONLY_AST) 252 code = compile(tmp, filename, "exec", ast.PyCF_ONLY_AST)
263 if lineno is not None: 253 if lineno is not None:
264 ast.increment_lineno(code, lineno-1) 254 ast.increment_lineno(code, lineno-1)
diff --git a/bitbake/lib/bb/runqueue.py b/bitbake/lib/bb/runqueue.py
index b9dd830b31..ce711b6252 100644
--- a/bitbake/lib/bb/runqueue.py
+++ b/bitbake/lib/bb/runqueue.py
@@ -1511,7 +1511,7 @@ class RunQueue:
1511 1511
1512 if not self.dm_event_handler_registered: 1512 if not self.dm_event_handler_registered:
1513 res = bb.event.register(self.dm_event_handler_name, 1513 res = bb.event.register(self.dm_event_handler_name,
1514 lambda x: self.dm.check(self) if self.state in [runQueueRunning, runQueueCleanUp] else False, 1514 lambda x, y: self.dm.check(self) if self.state in [runQueueRunning, runQueueCleanUp] else False,
1515 ('bb.event.HeartbeatEvent',), data=self.cfgData) 1515 ('bb.event.HeartbeatEvent',), data=self.cfgData)
1516 self.dm_event_handler_registered = True 1516 self.dm_event_handler_registered = True
1517 1517
diff --git a/bitbake/lib/bb/tests/color.py b/bitbake/lib/bb/tests/color.py
index 88dd278006..bb70cb393d 100644
--- a/bitbake/lib/bb/tests/color.py
+++ b/bitbake/lib/bb/tests/color.py
@@ -20,7 +20,7 @@ class ProgressWatcher:
20 def __init__(self): 20 def __init__(self):
21 self._reports = [] 21 self._reports = []
22 22
23 def handle_event(self, event): 23 def handle_event(self, event, d):
24 self._reports.append((event.progress, event.rate)) 24 self._reports.append((event.progress, event.rate))
25 25
26 def reports(self): 26 def reports(self):
diff --git a/bitbake/lib/bb/tests/event.py b/bitbake/lib/bb/tests/event.py
index 9ca7e9bc8e..4de4cced5e 100644
--- a/bitbake/lib/bb/tests/event.py
+++ b/bitbake/lib/bb/tests/event.py
@@ -157,7 +157,7 @@ class EventHandlingTest(unittest.TestCase):
157 self._test_process.event_handler, 157 self._test_process.event_handler,
158 event, 158 event,
159 None) 159 None)
160 self._test_process.event_handler.assert_called_once_with(event) 160 self._test_process.event_handler.assert_called_once_with(event, None)
161 161
162 def test_fire_class_handlers(self): 162 def test_fire_class_handlers(self):
163 """ Test fire_class_handlers method """ 163 """ Test fire_class_handlers method """
@@ -175,10 +175,10 @@ class EventHandlingTest(unittest.TestCase):
175 bb.event.fire_class_handlers(event1, None) 175 bb.event.fire_class_handlers(event1, None)
176 bb.event.fire_class_handlers(event2, None) 176 bb.event.fire_class_handlers(event2, None)
177 bb.event.fire_class_handlers(event2, None) 177 bb.event.fire_class_handlers(event2, None)
178 expected_event_handler1 = [call(event1)] 178 expected_event_handler1 = [call(event1, None)]
179 expected_event_handler2 = [call(event1), 179 expected_event_handler2 = [call(event1, None),
180 call(event2), 180 call(event2, None),
181 call(event2)] 181 call(event2, None)]
182 self.assertEqual(self._test_process.event_handler1.call_args_list, 182 self.assertEqual(self._test_process.event_handler1.call_args_list,
183 expected_event_handler1) 183 expected_event_handler1)
184 self.assertEqual(self._test_process.event_handler2.call_args_list, 184 self.assertEqual(self._test_process.event_handler2.call_args_list,
@@ -205,7 +205,7 @@ class EventHandlingTest(unittest.TestCase):
205 bb.event.fire_class_handlers(event2, None) 205 bb.event.fire_class_handlers(event2, None)
206 bb.event.fire_class_handlers(event2, None) 206 bb.event.fire_class_handlers(event2, None)
207 expected_event_handler1 = [] 207 expected_event_handler1 = []
208 expected_event_handler2 = [call(event1)] 208 expected_event_handler2 = [call(event1, None)]
209 self.assertEqual(self._test_process.event_handler1.call_args_list, 209 self.assertEqual(self._test_process.event_handler1.call_args_list,
210 expected_event_handler1) 210 expected_event_handler1)
211 self.assertEqual(self._test_process.event_handler2.call_args_list, 211 self.assertEqual(self._test_process.event_handler2.call_args_list,
@@ -223,7 +223,7 @@ class EventHandlingTest(unittest.TestCase):
223 self.assertEqual(result, bb.event.Registered) 223 self.assertEqual(result, bb.event.Registered)
224 bb.event.fire_class_handlers(event1, None) 224 bb.event.fire_class_handlers(event1, None)
225 bb.event.fire_class_handlers(event2, None) 225 bb.event.fire_class_handlers(event2, None)
226 expected = [call(event1), call(event2)] 226 expected = [call(event1, None), call(event2, None)]
227 self.assertEqual(self._test_process.event_handler1.call_args_list, 227 self.assertEqual(self._test_process.event_handler1.call_args_list,
228 expected) 228 expected)
229 229
@@ -237,7 +237,7 @@ class EventHandlingTest(unittest.TestCase):
237 self.assertEqual(result, bb.event.Registered) 237 self.assertEqual(result, bb.event.Registered)
238 bb.event.fire_class_handlers(event1, None) 238 bb.event.fire_class_handlers(event1, None)
239 bb.event.fire_class_handlers(event2, None) 239 bb.event.fire_class_handlers(event2, None)
240 expected = [call(event1), call(event2), call(event1)] 240 expected = [call(event1, None), call(event2, None), call(event1, None)]
241 self.assertEqual(self._test_process.event_handler1.call_args_list, 241 self.assertEqual(self._test_process.event_handler1.call_args_list,
242 expected) 242 expected)
243 243
@@ -251,7 +251,7 @@ class EventHandlingTest(unittest.TestCase):
251 self.assertEqual(result, bb.event.Registered) 251 self.assertEqual(result, bb.event.Registered)
252 bb.event.fire_class_handlers(event1, None) 252 bb.event.fire_class_handlers(event1, None)
253 bb.event.fire_class_handlers(event2, None) 253 bb.event.fire_class_handlers(event2, None)
254 expected = [call(event1), call(event2), call(event1), call(event2)] 254 expected = [call(event1,None), call(event2, None), call(event1, None), call(event2, None)]
255 self.assertEqual(self._test_process.event_handler1.call_args_list, 255 self.assertEqual(self._test_process.event_handler1.call_args_list,
256 expected) 256 expected)
257 257
@@ -359,9 +359,10 @@ class EventHandlingTest(unittest.TestCase):
359 359
360 event1 = bb.event.ConfigParsed() 360 event1 = bb.event.ConfigParsed()
361 bb.event.fire(event1, None) 361 bb.event.fire(event1, None)
362 expected = [call(event1)] 362 expected = [call(event1, None)]
363 self.assertEqual(self._test_process.event_handler1.call_args_list, 363 self.assertEqual(self._test_process.event_handler1.call_args_list,
364 expected) 364 expected)
365 expected = [call(event1)]
365 self.assertEqual(self._test_ui1.event.send.call_args_list, 366 self.assertEqual(self._test_ui1.event.send.call_args_list,
366 expected) 367 expected)
367 368