summaryrefslogtreecommitdiffstats
path: root/bitbake
diff options
context:
space:
mode:
authorRichard Purdie <richard.purdie@linuxfoundation.org>2020-09-02 23:14:04 +0100
committerRichard Purdie <richard.purdie@linuxfoundation.org>2020-09-08 10:18:02 +0100
commit1ba387a12c43f519d0b172ec169726331c4de25f (patch)
tree47e9d58863c84cc668d463913efbc3da214b30cf /bitbake
parentf19f252e2bad84524d61a743effac9e43e64c4e2 (diff)
downloadpoky-1ba387a12c43f519d0b172ec169726331c4de25f.tar.gz
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 <richard.purdie@linuxfoundation.org>
Diffstat (limited to 'bitbake')
-rw-r--r--bitbake/lib/bb/cooker.py10
1 files changed, 6 insertions, 4 deletions
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):
1993 except queue.Empty: 1993 except queue.Empty:
1994 pass 1994 pass
1995 else: 1995 else:
1996 self.results.cancel_join_thread() 1996 self.results.close()
1997 self.results.join_thread()
1997 break 1998 break
1998 1999
1999 if pending: 2000 if pending:
@@ -2002,6 +2003,8 @@ class Parser(multiprocessing.Process):
2002 try: 2003 try:
2003 job = self.jobs.pop() 2004 job = self.jobs.pop()
2004 except IndexError: 2005 except IndexError:
2006 self.results.close()
2007 self.results.join_thread()
2005 break 2008 break
2006 result = self.parse(*job) 2009 result = self.parse(*job)
2007 # Clear the siggen cache after parsing to control memory usage, its huge 2010 # Clear the siggen cache after parsing to control memory usage, its huge
@@ -2121,8 +2124,6 @@ class CookerParser(object):
2121 2124
2122 bb.event.fire(event, self.cfgdata) 2125 bb.event.fire(event, self.cfgdata)
2123 2126
2124 # Allow data left in the cancel queue to be discarded
2125 self.parser_quit.cancel_join_thread()
2126 for process in self.processes: 2127 for process in self.processes:
2127 self.parser_quit.put(None) 2128 self.parser_quit.put(None)
2128 2129
@@ -2142,7 +2143,8 @@ class CookerParser(object):
2142 process.join() 2143 process.join()
2143 2144
2144 self.parser_quit.close() 2145 self.parser_quit.close()
2145 self.parser_quit.join_thread() 2146 # Allow data left in the cancel queue to be discarded
2147 self.parser_quit.cancel_join_thread()
2146 2148
2147 def sync_caches(): 2149 def sync_caches():
2148 for c in self.bb_caches.values(): 2150 for c in self.bb_caches.values():