[Spice-devel] [PATCH spice-server 1/4] red-client: Prevent RedChannelClient creation when the RedClient is being destroyed

Christophe Fergeau cfergeau at redhat.com
Thu Aug 31 14:59:46 UTC 2017


Acked-by: Christophe Fergeau <cfergeau at redhat.com>

On Wed, Aug 30, 2017 at 01:51:25PM +0100, Frediano Ziglio wrote:
> This can happen as the connection is asynchronous so (MT main thread,
> CT channel thread):
> - MT you get a new connection;
> - MT a connection is sent to CT;
> - MT you get a disconnection of main channel;
> - MT red_client_destroy is called;
> - CT you attempt to add the RCC to RedClient.
> 
> Signed-off-by: Frediano Ziglio <fziglio at redhat.com>
> ---
>  server/red-client.c | 19 ++++++++++++++++++-
>  1 file changed, 18 insertions(+), 1 deletion(-)
> 
> diff --git a/server/red-client.c b/server/red-client.c
> index 666903e3..ddfc5400 100644
> --- a/server/red-client.c
> +++ b/server/red-client.c
> @@ -202,6 +202,7 @@ void red_client_destroy(RedClient *client)
>                        client->thread_id,
>                        pthread_self());
>      }
> +    red_client_set_disconnecting(client);
>      FOREACH_CHANNEL_CLIENT(client, rcc) {
>          RedChannel *channel;
>          // some channels may be in other threads, so disconnection
> @@ -254,6 +255,16 @@ gboolean red_client_add_channel(RedClient *client, RedChannelClient *rcc, GError
>      pthread_mutex_lock(&client->lock);
>  
>      g_object_get(channel, "channel-type", &type, "id", &id, NULL);
> +    if (client->disconnecting) {
> +        g_set_error(error,
> +                    SPICE_SERVER_ERROR,
> +                    SPICE_SERVER_ERROR_FAILED,
> +                    "Client %p got disconnected while connecting channel type %d id %d",
> +                    client, type, id);
> +        result = FALSE;
> +        goto cleanup;
> +    }
> +
>      if (red_client_get_channel(client, type, id)) {
>          g_set_error(error,
>                      SPICE_SERVER_ERROR,
> @@ -347,12 +358,18 @@ gboolean red_client_seamless_migration_done_for_channel(RedClient *client)
>  
>  gboolean red_client_is_disconnecting(RedClient *client)
>  {
> -    return client->disconnecting;
> +    gboolean ret;
> +    pthread_mutex_lock(&client->lock);
> +    ret =  client->disconnecting;
> +    pthread_mutex_unlock(&client->lock);
> +    return ret;
>  }
>  
>  void red_client_set_disconnecting(RedClient *client)
>  {
> +    pthread_mutex_lock(&client->lock);
>      client->disconnecting = TRUE;
> +    pthread_mutex_unlock(&client->lock);
>  }
>  
>  RedsState *red_client_get_server(RedClient *client)
> -- 
> 2.13.5
> 
> _______________________________________________
> Spice-devel mailing list
> Spice-devel at lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/spice-devel


More information about the Spice-devel mailing list