diff options
| author | Richard Purdie <richard.purdie@linuxfoundation.org> | 2020-09-02 23:14:04 +0100 |
|---|---|---|
| committer | Richard Purdie <richard.purdie@linuxfoundation.org> | 2020-09-08 10:18:02 +0100 |
| commit | 1ba387a12c43f519d0b172ec169726331c4de25f (patch) | |
| tree | 47e9d58863c84cc668d463913efbc3da214b30cf /bitbake/lib | |
| parent | f19f252e2bad84524d61a743effac9e43e64c4e2 (diff) | |
| download | poky-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/lib')
| -rw-r--r-- | bitbake/lib/bb/cooker.py | 10 |
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(): |
