From 1ba387a12c43f519d0b172ec169726331c4de25f Mon Sep 17 00:00:00 2001 From: Richard Purdie Date: Wed, 2 Sep 2020 23:14:04 +0100 Subject: bitbake: cooker: Avoid parser deadlocks If you make parsing fail (e.g. add something like: X := "${@d.getVar('MCMACHINES').split()[1]}" to meson.bbclass, then run "while true; do bitbake -g bash; done" it will eventually hang. It appears the cancel_join_thread() call the parsing failure triggers, breaks the results_queue badly enough that it sits in read() indefintely (called from self.result_queue.get(timeout=0.25)). The timeout only applies to lock aquisition, not the read call. I've tried various other approaches such as using cancel_join_thread() in other places but the only way things don't lock up is to avoid cancel_join_thread() entirely for results_queue. I do have a concern that this may adversely affect Ctrl+C handling but equally, its broken now already and this appears to improve things. [YOCTO #14034] (Bitbake rev: 9c61a1cc7be46c23da1f4ef3bee070fb83c4be57) Signed-off-by: Richard Purdie --- bitbake/lib/bb/cooker.py | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) (limited to 'bitbake') diff --git a/bitbake/lib/bb/cooker.py b/bitbake/lib/bb/cooker.py index e781ff8b30..7de3df018d 100644 --- a/bitbake/lib/bb/cooker.py +++ b/bitbake/lib/bb/cooker.py @@ -1993,7 +1993,8 @@ class Parser(multiprocessing.Process): except queue.Empty: pass else: - self.results.cancel_join_thread() + self.results.close() + self.results.join_thread() break if pending: @@ -2002,6 +2003,8 @@ class Parser(multiprocessing.Process): try: job = self.jobs.pop() except IndexError: + self.results.close() + self.results.join_thread() break result = self.parse(*job) # Clear the siggen cache after parsing to control memory usage, its huge @@ -2121,8 +2124,6 @@ class CookerParser(object): bb.event.fire(event, self.cfgdata) - # Allow data left in the cancel queue to be discarded - self.parser_quit.cancel_join_thread() for process in self.processes: self.parser_quit.put(None) @@ -2142,7 +2143,8 @@ class CookerParser(object): process.join() self.parser_quit.close() - self.parser_quit.join_thread() + # Allow data left in the cancel queue to be discarded + self.parser_quit.cancel_join_thread() def sync_caches(): for c in self.bb_caches.values(): -- cgit v1.2.3-54-g00ecf