[Spice-devel] [spice-server 08/17] sound: Implement snd_channel_config_socket

Frediano Ziglio fziglio at redhat.com
Wed Jan 11 11:28:06 UTC 2017


> 
> This is in preparation for switching SndChannelClient into a proper
> RedChannelClient. The prototype of the new helper matches what is
> expected from the RedChannel::config_socket vfunc.
> 
> To be able to achieve that, this commit associates the sound channel
> RedsStream instance with the DummyChannelClient instance we have, and
> then call snd_channel_config_socket() on that instance.
> 
> Based on a patch from Frediano Ziglio <fziglio at redhat.com>
> 
> Signed-off-by: Christophe Fergeau <cfergeau at redhat.com>
> ---
>  server/dummy-channel-client.c |  2 +
>  server/dummy-channel-client.h |  1 +
>  server/sound.c                | 96
>  ++++++++++++++++++++++---------------------
>  3 files changed, 53 insertions(+), 46 deletions(-)
> 
> diff --git a/server/dummy-channel-client.c b/server/dummy-channel-client.c
> index 61d5683..4efaa31 100644
> --- a/server/dummy-channel-client.c
> +++ b/server/dummy-channel-client.c
> @@ -104,6 +104,7 @@ dummy_channel_client_init(DummyChannelClient *self)
>  
>  RedChannelClient* dummy_channel_client_create(RedChannel *channel,
>                                                RedClient  *client,
> +                                              RedsStream *stream,
>                                                int num_common_caps,
>                                                uint32_t *common_caps,
>                                                int num_caps, uint32_t *caps)
> @@ -125,6 +126,7 @@ RedChannelClient* dummy_channel_client_create(RedChannel
> *channel,
>                           NULL, NULL,
>                           "channel", channel,
>                           "client", client,
> +                         "stream", stream,
>                           "caps", caps_array,
>                           "common-caps", common_caps_array,
>                           NULL);
> diff --git a/server/dummy-channel-client.h b/server/dummy-channel-client.h
> index 8013aa2..54e0e6c 100644
> --- a/server/dummy-channel-client.h
> +++ b/server/dummy-channel-client.h
> @@ -56,6 +56,7 @@ GType dummy_channel_client_get_type(void) G_GNUC_CONST;
>  
>  RedChannelClient *dummy_channel_client_create(RedChannel *channel,
>                                                RedClient  *client,
> +                                              RedsStream *stream,
>                                                int num_common_caps, uint32_t
>                                                *common_caps,
>                                                int num_caps, uint32_t *caps);
>  
> diff --git a/server/sound.c b/server/sound.c
> index bd9bb66..e1d6805 100644
> --- a/server/sound.c
> +++ b/server/sound.c
> @@ -925,6 +925,8 @@ static void snd_record_send(void* data)
>      }
>  }
>  
> +static int snd_channel_config_socket(RedChannelClient *rcc);
> +
>  static SndChannelClient *__new_channel(SndChannel *channel, int size,
>  uint32_t channel_id,
>                                         RedClient *red_client,
>                                         RedsStream *stream,
> @@ -936,50 +938,8 @@ static SndChannelClient *__new_channel(SndChannel
> *channel, int size, uint32_t c
>                                         uint32_t *caps, int num_caps)
>  {
>      SndChannelClient *client;
> -    int delay_val;
> -    int flags;
> -#ifdef SO_PRIORITY
> -    int priority;
> -#endif
> -    int tos;
> -    MainChannelClient *mcc = red_client_get_main(red_client);
>      RedsState *reds = red_channel_get_server(RED_CHANNEL(channel));
>  
> -    spice_assert(stream);
> -    if ((flags = fcntl(stream->socket, F_GETFL)) == -1) {
> -        spice_printerr("accept failed, %s", strerror(errno));
> -        goto error1;
> -    }
> -
> -#ifdef SO_PRIORITY
> -    priority = 6;
> -    if (setsockopt(stream->socket, SOL_SOCKET, SO_PRIORITY,
> (void*)&priority,
> -                   sizeof(priority)) == -1) {
> -        if (errno != ENOTSUP) {
> -            spice_printerr("setsockopt failed, %s", strerror(errno));
> -        }
> -    }
> -#endif
> -
> -    tos = IPTOS_LOWDELAY;
> -    if (setsockopt(stream->socket, IPPROTO_IP, IP_TOS, (void*)&tos,
> sizeof(tos)) == -1) {
> -        if (errno != ENOTSUP) {
> -            spice_printerr("setsockopt failed, %s", strerror(errno));
> -        }
> -    }
> -
> -    delay_val = main_channel_client_is_low_bandwidth(mcc) ? 0 : 1;
> -    if (setsockopt(stream->socket, IPPROTO_TCP, TCP_NODELAY, &delay_val,
> sizeof(delay_val)) == -1) {
> -        if (errno != ENOTSUP) {
> -            spice_printerr("setsockopt failed, %s", strerror(errno));
> -        }
> -    }
> -
> -    if (fcntl(stream->socket, F_SETFL, flags | O_NONBLOCK) == -1) {
> -        spice_printerr("accept failed, %s", strerror(errno));
> -        goto error1;
> -    }
> -
>      spice_assert(size >= sizeof(*client));
>      client = spice_malloc0(size);
>      client->refs = 1;
> @@ -1004,24 +964,68 @@ static SndChannelClient *__new_channel(SndChannel
> *channel, int size, uint32_t c
>      client->cleanup = cleanup;
>  
>      client->channel_client =
> -        dummy_channel_client_create(RED_CHANNEL(channel), red_client,
> +        dummy_channel_client_create(RED_CHANNEL(channel), red_client,
> stream,
>                                      num_common_caps, common_caps, num_caps,
>                                      caps);
>      if (!client->channel_client) {
>          goto error2;
>      }
> +    snd_channel_config_socket(RED_CHANNEL_CLIENT(client->channel_client));
> +

This assumes the function never fails.

>      return client;
>  
>  error2:
>      free(client);
> -
> -error1:
>      reds_stream_free(stream);
>      return NULL;
>  }
>  
>  static int snd_channel_config_socket(RedChannelClient *rcc)
>  {
> -    g_assert_not_reached();
> +    int delay_val;
> +    int flags;
> +#ifdef SO_PRIORITY
> +    int priority;
> +#endif
> +    int tos;
> +    RedsStream *stream = red_channel_client_get_stream(rcc);
> +    RedClient *red_client = red_channel_client_get_client(rcc);
> +    MainChannelClient *mcc = red_client_get_main(red_client);
> +
> +    if ((flags = fcntl(stream->socket, F_GETFL)) == -1) {
> +        spice_printerr("accept failed, %s", strerror(errno));
> +        return FALSE;
> +    }
> +
> +#ifdef SO_PRIORITY
> +    priority = 6;
> +    if (setsockopt(stream->socket, SOL_SOCKET, SO_PRIORITY,
> (void*)&priority,
> +                   sizeof(priority)) == -1) {
> +        if (errno != ENOTSUP) {
> +            spice_printerr("setsockopt failed, %s", strerror(errno));
> +        }
> +    }
> +#endif
> +
> +    tos = IPTOS_LOWDELAY;
> +    if (setsockopt(stream->socket, IPPROTO_IP, IP_TOS, (void*)&tos,
> sizeof(tos)) == -1) {
> +        if (errno != ENOTSUP) {
> +            spice_printerr("setsockopt failed, %s", strerror(errno));
> +        }
> +    }
> +
> +    delay_val = main_channel_client_is_low_bandwidth(mcc) ? 0 : 1;
> +    if (setsockopt(stream->socket, IPPROTO_TCP, TCP_NODELAY, &delay_val,
> sizeof(delay_val)) == -1) {
> +        if (errno != ENOTSUP) {
> +            spice_printerr("setsockopt failed, %s", strerror(errno));
> +        }
> +    }
> +
> +    if (fcntl(stream->socket, F_SETFL, flags | O_NONBLOCK) == -1) {
> +        spice_printerr("accept failed, %s", strerror(errno));
> +        return FALSE;
> +    }
> +
> +    return TRUE;
>  }
>  
>  static void snd_channel_on_disconnect(RedChannelClient *rcc)

Frediano


More information about the Spice-devel mailing list