summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRichard Purdie <richard.purdie@linuxfoundation.org>2022-12-21 14:43:06 +0000
committerRichard Purdie <richard.purdie@linuxfoundation.org>2022-12-31 17:05:17 +0000
commit6a6a5c01f768f2af581f1f764a3a1c40864459e7 (patch)
treefa23ecd0e0935fd3f62f455770e28b476858854b
parentc4ecfc4dc5511a23e12ed68eb140a67fd4181127 (diff)
downloadpoky-6a6a5c01f768f2af581f1f764a3a1c40864459e7.tar.gz
bitbake: event: Always use threadlock
With the move to a server idle thread, we always need threading. The existing accessor functions could end up turning this off! I was going to hold the lock whilst changing it, check if the value was already set, cache the result and also fix the event code to always release the lock with a try/finally. Instead, disable the existing functions and use a with: block to handle the lock, keeping things much simpler. (Bitbake rev: 645c9d3b50e55f69b222cc338373cdfd91d524ce) Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
-rw-r--r--bitbake/lib/bb/event.py73
-rw-r--r--bitbake/lib/bb/tests/event.py17
2 files changed, 35 insertions, 55 deletions
diff --git a/bitbake/lib/bb/event.py b/bitbake/lib/bb/event.py
index db90724444..7826541a64 100644
--- a/bitbake/lib/bb/event.py
+++ b/bitbake/lib/bb/event.py
@@ -68,16 +68,15 @@ _catchall_handlers = {}
68_eventfilter = None 68_eventfilter = None
69_uiready = False 69_uiready = False
70_thread_lock = threading.Lock() 70_thread_lock = threading.Lock()
71_thread_lock_enabled = False
72_heartbeat_enabled = False 71_heartbeat_enabled = False
73 72
74def enable_threadlock(): 73def enable_threadlock():
75 global _thread_lock_enabled 74 # Always needed now
76 _thread_lock_enabled = True 75 return
77 76
78def disable_threadlock(): 77def disable_threadlock():
79 global _thread_lock_enabled 78 # Always needed now
80 _thread_lock_enabled = False 79 return
81 80
82def enable_heartbeat(): 81def enable_heartbeat():
83 global _heartbeat_enabled 82 global _heartbeat_enabled
@@ -179,36 +178,30 @@ def print_ui_queue():
179 178
180def fire_ui_handlers(event, d): 179def fire_ui_handlers(event, d):
181 global _thread_lock 180 global _thread_lock
182 global _thread_lock_enabled
183 181
184 if not _uiready: 182 if not _uiready:
185 # No UI handlers registered yet, queue up the messages 183 # No UI handlers registered yet, queue up the messages
186 ui_queue.append(event) 184 ui_queue.append(event)
187 return 185 return
188 186
189 if _thread_lock_enabled: 187 with _thread_lock:
190 _thread_lock.acquire() 188 errors = []
191 189 for h in _ui_handlers:
192 errors = [] 190 #print "Sending event %s" % event
193 for h in _ui_handlers: 191 try:
194 #print "Sending event %s" % event 192 if not _ui_logfilters[h].filter(event):
195 try: 193 continue
196 if not _ui_logfilters[h].filter(event): 194 # We use pickle here since it better handles object instances
197 continue 195 # which xmlrpc's marshaller does not. Events *must* be serializable
198 # We use pickle here since it better handles object instances 196 # by pickle.
199 # which xmlrpc's marshaller does not. Events *must* be serializable 197 if hasattr(_ui_handlers[h].event, "sendpickle"):
200 # by pickle. 198 _ui_handlers[h].event.sendpickle((pickle.dumps(event)))
201 if hasattr(_ui_handlers[h].event, "sendpickle"): 199 else:
202 _ui_handlers[h].event.sendpickle((pickle.dumps(event))) 200 _ui_handlers[h].event.send(event)
203 else: 201 except:
204 _ui_handlers[h].event.send(event) 202 errors.append(h)
205 except: 203 for h in errors:
206 errors.append(h) 204 del _ui_handlers[h]
207 for h in errors:
208 del _ui_handlers[h]
209
210 if _thread_lock_enabled:
211 _thread_lock.release()
212 205
213def fire(event, d): 206def fire(event, d):
214 """Fire off an Event""" 207 """Fire off an Event"""
@@ -322,21 +315,23 @@ def set_eventfilter(func):
322 _eventfilter = func 315 _eventfilter = func
323 316
324def register_UIHhandler(handler, mainui=False): 317def register_UIHhandler(handler, mainui=False):
325 bb.event._ui_handler_seq = bb.event._ui_handler_seq + 1 318 with _thread_lock:
326 _ui_handlers[_ui_handler_seq] = handler 319 bb.event._ui_handler_seq = bb.event._ui_handler_seq + 1
327 level, debug_domains = bb.msg.constructLogOptions() 320 _ui_handlers[_ui_handler_seq] = handler
328 _ui_logfilters[_ui_handler_seq] = UIEventFilter(level, debug_domains) 321 level, debug_domains = bb.msg.constructLogOptions()
329 if mainui: 322 _ui_logfilters[_ui_handler_seq] = UIEventFilter(level, debug_domains)
330 global _uiready 323 if mainui:
331 _uiready = _ui_handler_seq 324 global _uiready
332 return _ui_handler_seq 325 _uiready = _ui_handler_seq
326 return _ui_handler_seq
333 327
334def unregister_UIHhandler(handlerNum, mainui=False): 328def unregister_UIHhandler(handlerNum, mainui=False):
335 if mainui: 329 if mainui:
336 global _uiready 330 global _uiready
337 _uiready = False 331 _uiready = False
338 if handlerNum in _ui_handlers: 332 with _thread_lock:
339 del _ui_handlers[handlerNum] 333 if handlerNum in _ui_handlers:
334 del _ui_handlers[handlerNum]
340 return 335 return
341 336
342def get_uihandler(): 337def get_uihandler():
diff --git a/bitbake/lib/bb/tests/event.py b/bitbake/lib/bb/tests/event.py
index 4de4cced5e..d959f2d95d 100644
--- a/bitbake/lib/bb/tests/event.py
+++ b/bitbake/lib/bb/tests/event.py
@@ -451,10 +451,9 @@ class EventHandlingTest(unittest.TestCase):
451 and disable threadlocks tests """ 451 and disable threadlocks tests """
452 bb.event.fire(bb.event.OperationStarted(), None) 452 bb.event.fire(bb.event.OperationStarted(), None)
453 453
454 def test_enable_threadlock(self): 454 def test_event_threadlock(self):
455 """ Test enable_threadlock method """ 455 """ Test enable_threadlock method """
456 self._set_threadlock_test_mockups() 456 self._set_threadlock_test_mockups()
457 bb.event.enable_threadlock()
458 self._set_and_run_threadlock_test_workers() 457 self._set_and_run_threadlock_test_workers()
459 # Calls to UI handlers should be in order as all the registered 458 # Calls to UI handlers should be in order as all the registered
460 # handlers for the event coming from the first worker should be 459 # handlers for the event coming from the first worker should be
@@ -462,20 +461,6 @@ class EventHandlingTest(unittest.TestCase):
462 self.assertEqual(self._threadlock_test_calls, 461 self.assertEqual(self._threadlock_test_calls,
463 ["w1_ui1", "w1_ui2", "w2_ui1", "w2_ui2"]) 462 ["w1_ui1", "w1_ui2", "w2_ui1", "w2_ui2"])
464 463
465
466 def test_disable_threadlock(self):
467 """ Test disable_threadlock method """
468 self._set_threadlock_test_mockups()
469 bb.event.disable_threadlock()
470 self._set_and_run_threadlock_test_workers()
471 # Calls to UI handlers should be intertwined together. Thanks to the
472 # delay in the registered handlers for the event coming from the first
473 # worker, the event coming from the second worker starts being
474 # processed before finishing handling the first worker event.
475 self.assertEqual(self._threadlock_test_calls,
476 ["w1_ui1", "w2_ui1", "w1_ui2", "w2_ui2"])
477
478
479class EventClassesTest(unittest.TestCase): 464class EventClassesTest(unittest.TestCase):
480 """ Event classes test class """ 465 """ Event classes test class """
481 466