[PATCH weston v4] libweston-desktop: fix stale ping when a wl_shell_surface is destroyed
Giulio Camuffo
giuliocamuffo at gmail.com
Thu Dec 8 15:52:17 UTC 2016
2016-12-08 16:46 GMT+01:00 Quentin Glidic <sardemff7+wayland at sardemff7.net>:
> On 08/12/2016 16:20, Giulio Camuffo wrote:
>>
>> When sending a ping event to a surface using the wl_shell interface,
>> if that surface is destroyed before we receive the pong we will never
>> receive it, even if the client is actually responsive, since the
>> interface does not exist anymore. So when the surface if destroyed
>> pretend it's a pong and reset the ping state.
>>
>> Signed-off-by: Giulio Camuffo <giuliocamuffo at gmail.com>
>
>
> I made a few renames to match the current code.
> I was going to push it, but I found a last issue, see below.
>
>
>> ---
>>
>> v3: store the ping serial in the surface instead of the client wrapper
>> v4: removed leftover change
>>
>> libweston-desktop/wl-shell.c | 22 +++++++++++++++++++++-
>> 1 file changed, 21 insertions(+), 1 deletion(-)
>>
>> diff --git a/libweston-desktop/wl-shell.c b/libweston-desktop/wl-shell.c
>> index 399139c..f75b022 100644
>> --- a/libweston-desktop/wl-shell.c
>> +++ b/libweston-desktop/wl-shell.c
>> @@ -57,6 +57,7 @@ struct weston_desktop_wl_shell_surface {
>> struct weston_desktop_seat *popup_seat;
>> enum weston_desktop_wl_shell_surface_state state;
>> struct wl_listener wl_surface_resource_destroy_listener;
>> + uint32_t ping_serial;
>> };
>>
>> static void
>> @@ -112,6 +113,7 @@ weston_desktop_wl_shell_surface_ping(struct
>> weston_desktop_surface *dsurface,
>> {
>> struct weston_desktop_wl_shell_surface *surface = user_data;
>>
>> + surface->ping_serial = serial;
>> wl_shell_surface_send_ping(surface->resource, serial);
>> }
>>
>> @@ -181,11 +183,27 @@ weston_desktop_wl_shell_change_state(struct
>> weston_desktop_wl_shell_surface *sur
>> }
>>
>> static void
>> +pong_client(struct weston_desktop_wl_shell_surface *surface)
>
>
> weston_desktop_wl_shell_surface_pong_client
>
>> +{
>> + struct weston_desktop_client *client =
>> + weston_desktop_surface_get_client(surface->surface);
>> +
>> + weston_desktop_client_pong(client, surface->ping_serial);
>> + surface->ping_serial = 0;
>> +}
>> +
>> +static void
>> weston_desktop_wl_shell_surface_destroy(struct weston_desktop_surface
>> *dsurface,
>> void *user_data)
>> {
>> struct weston_desktop_wl_shell_surface *surface = user_data;
>>
>> + /* If the surface being destroyed was the one that was pinged
>> before
>> + * we need to fake a pong here, because it cannot answer the ping
>> anymore,
>> + * even if the client is responsive. */
>> + if (surface->ping_serial != 0)
>> + pong_client(surface);
>> +
>>
>> wl_list_remove(&surface->wl_surface_resource_destroy_listener.link);
>>
>> weston_desktop_wl_shell_surface_maybe_ungrab(surface);
>> @@ -203,8 +221,10 @@ weston_desktop_wl_shell_surface_protocol_pong(struct
>> wl_client *wl_client,
>> uint32_t serial)
>> {
>> struct weston_desktop_surface *surface =
>> wl_resource_get_user_data(resource);
>
>
> dsurface
>
>> + struct weston_desktop_wl_shell_surface *wls =
>> + weston_desktop_surface_get_implementation_data(surface);
>
>
> surface
>
>> -
>> weston_desktop_client_pong(weston_desktop_surface_get_client(surface),
>> serial);
>> + pong_client(wls);
>
>
> We should check that surface->ping_serial == serial somehow.
> Maybe it is safe to ignore serial for now, as it fixes something, then add a
> check in a follow-up commit.
Well, but weston_desktop_client_pong() already checks that, so i don't
think we need to check it here too.
>
> Thoughts? Pekka (aka assertman)?
>
> Cheers,
>
>
>> }
>>
>> static void
>>
>
>
> --
>
> Quentin “Sardem FF7” Glidic
More information about the wayland-devel
mailing list