On Thu, Jun 25, 2015 at 03:49:49PM -0500, Derek Foreman wrote:
> We really don't want to deal with sighups and pids.  It's far easier
> to just deal with the client destroyed signal to respawn the input method.
> 
> Inspiration taken from Pekka's commit 826dc14ec43b92d
> 
> This fixes a potential crash on shutdown.  If the input method client
> pointer is still set (sighup handler hasn't run) but the client is
> already destroyed, a call to text_backend_destroy() will try to destroy
> the client a second time resulting in a segfault.
> 
> Signed-off-by: Derek Foreman <[email protected]>

Pekka might want to review this, but LGTM for landing post-release.

Reviewed-by: Bryce Harrington <[email protected]>

> ---
>  src/text-backend.c | 47 +++++++++++++++++++++++++++++------------------
>  1 file changed, 29 insertions(+), 18 deletions(-)
> 
> diff --git a/src/text-backend.c b/src/text-backend.c
> index 59011c8..609bd71 100644
> --- a/src/text-backend.c
> +++ b/src/text-backend.c
> @@ -100,13 +100,13 @@ struct text_backend {
>  
>       struct {
>               char *path;
> -             struct weston_process process;
>               struct wl_client *client;
>  
>               unsigned deathcount;
>               uint32_t deathstamp;
>       } input_method;
>  
> +     struct wl_listener client_listener;
>       struct wl_listener seat_created_listener;
>  };
>  
> @@ -919,14 +919,9 @@ input_method_init_seat(struct weston_seat *seat)
>  static void launch_input_method(struct text_backend *text_backend);
>  
>  static void
> -handle_input_method_sigchld(struct weston_process *process, int status)
> +respawn_input_method_process(struct text_backend *text_backend)
>  {
>       uint32_t time;
> -     struct text_backend *text_backend =
> -             container_of(process, struct text_backend, 
> input_method.process);
> -
> -     text_backend->input_method.process.pid = 0;
> -     text_backend->input_method.client = NULL;
>  
>       /* if input_method dies more than 5 times in 10 seconds, give up */
>       time = weston_compositor_get_time();
> @@ -937,15 +932,27 @@ handle_input_method_sigchld(struct weston_process 
> *process, int status)
>  
>       text_backend->input_method.deathcount++;
>       if (text_backend->input_method.deathcount > 5) {
> -             weston_log("input_method died, giving up.\n");
> +             weston_log("input_method disconnected, giving up.\n");
>               return;
>       }
>  
> -     weston_log("input_method died, respawning...\n");
> +     weston_log("input_method disconnected, respawning...\n");
>       launch_input_method(text_backend);
>  }
>  
>  static void
> +input_method_client_notifier(struct wl_listener *listener, void *data)
> +{
> +     struct text_backend *text_backend;
> +
> +     text_backend = container_of(listener, struct text_backend,
> +                                 client_listener);
> +
> +     text_backend->input_method.client = NULL;
> +     respawn_input_method_process(text_backend);
> +}
> +
> +static void
>  launch_input_method(struct text_backend *text_backend)
>  {
>       if (!text_backend->input_method.path)
> @@ -954,18 +961,19 @@ launch_input_method(struct text_backend *text_backend)
>       if (strcmp(text_backend->input_method.path, "") == 0)
>               return;
>  
> -     if (text_backend->input_method.process.pid != 0)
> -             return;
> -
>       text_backend->input_method.client =
> -             weston_client_launch(text_backend->compositor,
> -                                  &text_backend->input_method.process,
> -                                  text_backend->input_method.path,
> -                                  handle_input_method_sigchld);
> +             weston_client_start(text_backend->compositor,
> +                                 text_backend->input_method.path);
>  
> -     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->client_listener.notify = input_method_client_notifier;
> +     wl_client_add_destroy_listener(text_backend->input_method.client,
> +                                    &text_backend->client_listener);
>  }
>  
>  static void
> @@ -1028,8 +1036,11 @@ text_backend_configuration(struct text_backend 
> *text_backend)
>  WL_EXPORT void
>  text_backend_destroy(struct text_backend *text_backend)
>  {
> -     if (text_backend->input_method.client)
> +     if (text_backend->input_method.client) {
> +             /* disable respawn */
> +             wl_list_remove(&text_backend->client_listener.link);
>               wl_client_destroy(text_backend->input_method.client);
> +     }
>  
>       free(text_backend->input_method.path);
>       free(text_backend);
> -- 
> 2.1.4
> 
> _______________________________________________
> wayland-devel mailing list
> [email protected]
> http://lists.freedesktop.org/mailman/listinfo/wayland-devel
_______________________________________________
wayland-devel mailing list
[email protected]
http://lists.freedesktop.org/mailman/listinfo/wayland-devel

Reply via email to