diff options
author | Richard Purdie <richard.purdie@linuxfoundation.org> | 2014-03-18 22:58:52 +0000 |
---|---|---|
committer | Richard Purdie <richard.purdie@linuxfoundation.org> | 2014-03-18 23:05:53 +0000 |
commit | 0150bc30d3674301631c2e9b6c64e01058fd1070 (patch) | |
tree | 40caf426b8e02aac158cd1c93e85a7c1b091cacd /bitbake/lib | |
parent | cfd1c4e79eb4e41e2090411adb8f7be2fbcc8e97 (diff) | |
download | poky-0150bc30d3674301631c2e9b6c64e01058fd1070.tar.gz |
bitbake: runqueue: Really fix sigchld handling
There are several problems. Firstly, a return value of "None" can mean
there is a C signal handler installed so we need to better handle that
case. signal.SIG_DFL is 0 which equates to false so we also need to
handle that by testing explicitly for None.
Finally, the signal handler *must* call waitpid on all child processes
else it will just get called repeatedly, leading to the hanging behaviour
we've been seeing. The solution is to only error for the worker children,
we warn about any other stray children which we'll have to figure out the
sources of in due course.
Hopefully this patch gets things working again properly though.
(Bitbake rev: 973876c706f08735c1b68c791a5a137e5f083dd2)
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
Diffstat (limited to 'bitbake/lib')
-rw-r--r-- | bitbake/lib/bb/runqueue.py | 28 |
1 files changed, 14 insertions, 14 deletions
diff --git a/bitbake/lib/bb/runqueue.py b/bitbake/lib/bb/runqueue.py index b71e1d0fcb..fa7a99fba1 100644 --- a/bitbake/lib/bb/runqueue.py +++ b/bitbake/lib/bb/runqueue.py | |||
@@ -914,32 +914,32 @@ class RunQueue: | |||
914 | workerpipe.close() | 914 | workerpipe.close() |
915 | 915 | ||
916 | def sigchild_exception(self, *args, **kwargs): | 916 | def sigchild_exception(self, *args, **kwargs): |
917 | for w in [self.worker, self.fakeworker]: | 917 | pid = -1 |
918 | if not w: | 918 | while pid: |
919 | continue | ||
920 | try: | 919 | try: |
921 | pid, status = os.waitpid(w.pid, os.WNOHANG) | 920 | pid, status = os.waitpid(-1, os.WNOHANG) |
922 | if pid != 0 and not self.teardown: | 921 | if pid != 0 and not self.teardown: |
922 | name = None | ||
923 | if self.worker and pid == self.worker.pid: | 923 | if self.worker and pid == self.worker.pid: |
924 | name = "Worker" | 924 | name = "Worker" |
925 | elif self.fakeworker and pid == self.fakeworker.pid: | 925 | elif self.fakeworker and pid == self.fakeworker.pid: |
926 | name = "Fakeroot" | 926 | name = "Fakeroot" |
927 | else: | 927 | else: |
928 | name = "Unknown" | 928 | bb.warn("Unknown process (%s) exited unexpectedly (%s), shutting down..." % (pid, str(status))) |
929 | bb.error("%s process (%s) exited unexpectedly (%s), shutting down..." % (name, pid, str(status))) | 929 | if name and not self.teardown: |
930 | self.finish_runqueue(True) | 930 | bb.error("%s process (%s) exited unexpectedly (%s), shutting down..." % (name, pid, str(status))) |
931 | self.finish_runqueue(True) | ||
931 | except OSError: | 932 | except OSError: |
932 | pid = False | 933 | return |
933 | if callable(self.oldsigchld) and self.oldsigchld != self.sigchild_exception: | ||
934 | self.oldsigchld(*args, **kwargs) | ||
935 | 934 | ||
936 | def start_worker(self): | 935 | def start_worker(self): |
937 | if self.worker: | 936 | if self.worker: |
938 | self.teardown_workers() | 937 | self.teardown_workers() |
939 | self.teardown = False | 938 | self.teardown = False |
940 | if not self.oldsigchld: | 939 | if self.oldsigchld is None: |
941 | self.oldsigchld = signal.getsignal(signal.SIGCHLD) | 940 | self.oldsigchld = signal.signal(signal.SIGCHLD, self.sigchild_exception) |
942 | signal.signal(signal.SIGCHLD, self.sigchild_exception) | 941 | if self.oldsigchld is None: |
942 | self.oldsigchld = signal.SIG_DFL | ||
943 | self.worker, self.workerpipe = self._start_worker() | 943 | self.worker, self.workerpipe = self._start_worker() |
944 | 944 | ||
945 | def start_fakeworker(self, rqexec): | 945 | def start_fakeworker(self, rqexec): |
@@ -948,7 +948,7 @@ class RunQueue: | |||
948 | 948 | ||
949 | def teardown_workers(self): | 949 | def teardown_workers(self): |
950 | self.teardown = True | 950 | self.teardown = True |
951 | if self.oldsigchld: | 951 | if self.oldsigchld is not None: |
952 | signal.signal(signal.SIGCHLD, self.oldsigchld) | 952 | signal.signal(signal.SIGCHLD, self.oldsigchld) |
953 | self.oldsigchld = None | 953 | self.oldsigchld = None |
954 | self._teardown_worker(self.worker, self.workerpipe) | 954 | self._teardown_worker(self.worker, self.workerpipe) |