summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRichard Purdie <richard.purdie@linuxfoundation.org>2021-06-15 12:00:33 -1000
committerRichard Purdie <richard.purdie@linuxfoundation.org>2021-06-19 17:06:18 +0100
commitf46f6af1f255544e4399e0ce4aee6ce9061a259d (patch)
treee78e5d7b6d469b7cc02768718c6f5943a90e8432
parentaa2c6a789aa883f504465b9203f2e76e5859e9eb (diff)
downloadpoky-f46f6af1f255544e4399e0ce4aee6ce9061a259d.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: 0e0af15b84e07e6763300dcd092b980086b9b9c4) Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org> Signed-off-by: Steve Sakoman <steve@sakoman.com> Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
-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 4d2c62cd96..730cdc56ff 100644
--- a/bitbake/lib/bb/cooker.py
+++ b/bitbake/lib/bb/cooker.py
@@ -1933,7 +1933,8 @@ class Parser(multiprocessing.Process):
1933 except queue.Empty: 1933 except queue.Empty:
1934 pass 1934 pass
1935 else: 1935 else:
1936 self.results.cancel_join_thread() 1936 self.results.close()
1937 self.results.join_thread()
1937 break 1938 break
1938 1939
1939 if pending: 1940 if pending:
@@ -1942,6 +1943,8 @@ class Parser(multiprocessing.Process):
1942 try: 1943 try:
1943 job = self.jobs.pop() 1944 job = self.jobs.pop()
1944 except IndexError: 1945 except IndexError:
1946 self.results.close()
1947 self.results.join_thread()
1945 break 1948 break
1946 result = self.parse(*job) 1949 result = self.parse(*job)
1947 # Clear the siggen cache after parsing to control memory usage, its huge 1950 # Clear the siggen cache after parsing to control memory usage, its huge
@@ -2060,8 +2063,6 @@ class CookerParser(object):
2060 2063
2061 bb.event.fire(event, self.cfgdata) 2064 bb.event.fire(event, self.cfgdata)
2062 2065
2063 # Allow data left in the cancel queue to be discarded
2064 self.parser_quit.cancel_join_thread()
2065 for process in self.processes: 2066 for process in self.processes:
2066 self.parser_quit.put(None) 2067 self.parser_quit.put(None)
2067 2068
@@ -2081,7 +2082,8 @@ class CookerParser(object):
2081 process.join() 2082 process.join()
2082 2083
2083 self.parser_quit.close() 2084 self.parser_quit.close()
2084 self.parser_quit.join_thread() 2085 # Allow data left in the cancel queue to be discarded
2086 self.parser_quit.cancel_join_thread()
2085 2087
2086 sync = threading.Thread(target=self.bb_cache.sync) 2088 sync = threading.Thread(target=self.bb_cache.sync)
2087 self.syncthread = sync 2089 self.syncthread = sync