diff options
author | Richard Purdie <richard.purdie@linuxfoundation.org> | 2022-12-21 14:43:06 +0000 |
---|---|---|
committer | Richard Purdie <richard.purdie@linuxfoundation.org> | 2022-12-31 17:05:17 +0000 |
commit | 6a6a5c01f768f2af581f1f764a3a1c40864459e7 (patch) | |
tree | fa23ecd0e0935fd3f62f455770e28b476858854b | |
parent | c4ecfc4dc5511a23e12ed68eb140a67fd4181127 (diff) | |
download | poky-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.py | 73 | ||||
-rw-r--r-- | bitbake/lib/bb/tests/event.py | 17 |
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 | ||
74 | def enable_threadlock(): | 73 | def enable_threadlock(): |
75 | global _thread_lock_enabled | 74 | # Always needed now |
76 | _thread_lock_enabled = True | 75 | return |
77 | 76 | ||
78 | def disable_threadlock(): | 77 | def disable_threadlock(): |
79 | global _thread_lock_enabled | 78 | # Always needed now |
80 | _thread_lock_enabled = False | 79 | return |
81 | 80 | ||
82 | def enable_heartbeat(): | 81 | def enable_heartbeat(): |
83 | global _heartbeat_enabled | 82 | global _heartbeat_enabled |
@@ -179,36 +178,30 @@ def print_ui_queue(): | |||
179 | 178 | ||
180 | def fire_ui_handlers(event, d): | 179 | def 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 | ||
213 | def fire(event, d): | 206 | def 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 | ||
324 | def register_UIHhandler(handler, mainui=False): | 317 | def 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 | ||
334 | def unregister_UIHhandler(handlerNum, mainui=False): | 328 | def 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 | ||
342 | def get_uihandler(): | 337 | def 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 | |||
479 | class EventClassesTest(unittest.TestCase): | 464 | class EventClassesTest(unittest.TestCase): |
480 | """ Event classes test class """ | 465 | """ Event classes test class """ |
481 | 466 | ||