[PATCH weston 3/3] compositor: leave no zombie behind

Pekka Paalanen ppaalanen at gmail.com
Wed Aug 27 03:41:45 PDT 2014


From: Pekka Paalanen <pekka.paalanen at collabora.co.uk>

When SIGCHLD fires, we may have more than one zombie to be collected.
Run waitpid() in a loop until no more zombies are found, and clean them
all up.

It looks like the SIGCHLD signalfd does not trigger again for remaining
zombies, so we need the loop.

This works around a crash in text_backend_notified_destroy, which ends
up using stale input_method.client if the sigchld handler is not called.
The crash could be triggered by removing both weston-desktop-shell and
weston-keyboard, so that both would try to respawn and give up, and then
quitting Weston.

Cc: rawoul at gmail.com
Cc: Boyan Ding <stu_dby at 126.com>
Cc: Derek Foreman <derekf at osg.samsung.com>
Signed-off-by: Pekka Paalanen <pekka.paalanen at collabora.co.uk>
---
 src/compositor.c | 26 ++++++++++++++------------
 1 file changed, 14 insertions(+), 12 deletions(-)

diff --git a/src/compositor.c b/src/compositor.c
index c62077c..8705950 100644
--- a/src/compositor.c
+++ b/src/compositor.c
@@ -46,6 +46,7 @@
 #include <setjmp.h>
 #include <sys/time.h>
 #include <time.h>
+#include <errno.h>
 
 #ifdef HAVE_LIBUNWIND
 #define UNW_LOCAL_ONLY
@@ -68,22 +69,23 @@ sigchld_handler(int signal_number, void *data)
 	int status;
 	pid_t pid;
 
-	pid = waitpid(-1, &status, WNOHANG);
-	if (!pid)
-		return 1;
+	while ((pid = waitpid(-1, &status, WNOHANG)) > 0) {
+		wl_list_for_each(p, &child_process_list, link) {
+			if (p->pid == pid)
+				break;
+		}
 
-	wl_list_for_each(p, &child_process_list, link) {
-		if (p->pid == pid)
-			break;
-	}
+		if (&p->link == &child_process_list) {
+			weston_log("unknown child process exited\n");
+			continue;
+		}
 
-	if (&p->link == &child_process_list) {
-		weston_log("unknown child process exited\n");
-		return 1;
+		wl_list_remove(&p->link);
+		p->cleanup(p, status);
 	}
 
-	wl_list_remove(&p->link);
-	p->cleanup(p, status);
+	if (pid < 0 && errno != ECHILD)
+		weston_log("waitpid error %m\n");
 
 	return 1;
 }
-- 
1.8.5.5



More information about the wayland-devel mailing list