From: Arnaud Vrac <[email protected]>

A crash could happen when killing weston, since the wayland client of
the shell child process could be destroyed twice: once when the wayland
client disconnects (before sigchld is caught), and then again when
destroying the shell.
---
 src/shell.c        | 21 ++++++++++++++++++++-
 src/text-backend.c | 21 ++++++++++++++++++++-
 2 files changed, 40 insertions(+), 2 deletions(-)

diff --git a/src/shell.c b/src/shell.c
index fe332e1..a1a3ea7 100644
--- a/src/shell.c
+++ b/src/shell.c
@@ -116,6 +116,7 @@ struct desktop_shell {
                struct weston_process process;
                struct wl_client *client;
                struct wl_resource *desktop_shell;
+               struct wl_listener client_destroy_listener;
 
                unsigned deathcount;
                uint32_t deathstamp;
@@ -3949,6 +3950,16 @@ desktop_shell_sigchld(struct weston_process *process, 
int status)
 }
 
 static void
+desktop_shell_handle_disconnect(struct wl_listener *listener, void *data)
+{
+       struct desktop_shell *shell =
+               container_of(listener, struct desktop_shell,
+                            child.client_destroy_listener);
+
+       shell->child.client = NULL;
+}
+
+static void
 launch_desktop_shell_process(void *data)
 {
        struct desktop_shell *shell = data;
@@ -3959,8 +3970,16 @@ launch_desktop_shell_process(void *data)
                                                 shell_exe,
                                                 desktop_shell_sigchld);
 
-       if (!shell->child.client)
+       if (!shell->child.client) {
                weston_log("not able to start %s\n", shell_exe);
+               return;
+       }
+
+       shell->child.client_destroy_listener.notify =
+               desktop_shell_handle_disconnect;
+
+       wl_client_add_destroy_listener(shell->child.client,
+                                      &shell->child.client_destroy_listener);
 }
 
 static void
diff --git a/src/text-backend.c b/src/text-backend.c
index 107ccd6..79544b2 100644
--- a/src/text-backend.c
+++ b/src/text-backend.c
@@ -95,6 +95,7 @@ struct text_backend {
                struct wl_resource *binding;
                struct weston_process process;
                struct wl_client *client;
+               struct wl_listener client_destroy_listener;
 
                unsigned deathcount;
                uint32_t deathstamp;
@@ -865,6 +866,16 @@ handle_input_method_sigchld(struct weston_process 
*process, int status)
 }
 
 static void
+handle_input_method_disconnect(struct wl_listener *listener, void *data)
+{
+       struct text_backend *text_backend =
+               container_of(listener, struct text_backend,
+                            input_method.client_destroy_listener);
+
+       text_backend->input_method.client = NULL;
+}
+
+static void
 launch_input_method(struct text_backend *text_backend)
 {
        if (text_backend->input_method.binding)
@@ -881,8 +892,16 @@ launch_input_method(struct text_backend *text_backend)
                                                                 
text_backend->input_method.path,
                                                                 
handle_input_method_sigchld);
 
-       if (!text_backend->input_method.client)
+       if (!text_backend->input_method.client) {
                weston_log("not able to start %s\n", 
text_backend->input_method.path);
+               return;
+       }
+
+       text_backend->input_method.client_destroy_listener.notify =
+               handle_input_method_disconnect;
+
+       wl_client_add_destroy_listener(text_backend->input_method.client,
+                                      
&text_backend->input_method.client_destroy_listener);
 }
 
 static void
-- 
1.8.3.2

_______________________________________________
wayland-devel mailing list
[email protected]
http://lists.freedesktop.org/mailman/listinfo/wayland-devel

Reply via email to