[Spice-devel] [spice-server] sound: Don't mute recording when client reconnects

Victor Toso victortoso at redhat.com
Thu May 24 07:09:16 UTC 2018


Hi,

Just to mention that I tested both patches and they work as
expected in the situation around rhbz#1549132

        toso

On Wed, May 23, 2018 at 01:36:35PM -0400, Frediano Ziglio wrote:
> > > When a new record channel is added, the code relies on a
> > > snd_send() call in record_channel_client_constructed() to
> > > send RECORD_START to the client. However, at this point,
> > > snd_send() is non-functional because the
> > > red_channel_client_pipe_add() call it makes is a no-op
> > > because prepare_pipe_add() makes a connection check through
> > > red_channel_client_is_connected() queueing the item. This
> > > connection
> >
> > The patch looks surely good, but why red_channel_client_is_connected
> > returns a wrong value? The channel is connected but asking if is
> > connected returns false... Is currently implemented as: is in the
> > channel list so is connected, otherwise is not which during construction
> > is wrong as still not in the list.
> > Won't be better to check if really connected?
> >
> > > check returns FALSE at ::constructed() time as the channel client will
> > > only become connected towards the end of
> > > red_channel_client_initable_init() which runs after the object
> > > instantiation is complete.
> > > 
> > 
> > For me a RCC is connected if there is a client connected at socket
> > level, being into a list of RCCs is not a really a great definition
> > for connected.
> > 
> > Maybe removing the check for red_channel_client_is_connected on
> > prepare_pipe_add would solve the issue?
> > 
> > > This causes a bug where starting recording and then
> > > disconnecting/reconnecting the client does not successfully reenable
> > > recording. This is a regression introduced by commit d8dc09
> > > 'sound: Convert SndChannelClient to RedChannelClient'
> > > 
> > > https://bugzilla.redhat.com/show_bug.cgi?id=1549132
> > > 
> > > Signed-off-by: Christophe Fergeau <cfergeau at redhat.com>
> > > ---
> > >  server/sound.c | 37 ++++++++++++++++++++++++++++++++++---
> > >  1 file changed, 34 insertions(+), 3 deletions(-)
> > > 
> > > diff --git a/server/sound.c b/server/sound.c
> > > index e3891d2cc..d461b9272 100644
> > > --- a/server/sound.c
> > > +++ b/server/sound.c
> > > @@ -105,7 +105,11 @@ typedef struct SndChannelClientClass {
> > >      RedChannelClientClass parent_class;
> > >  } SndChannelClientClass;
> > >  
> > > -G_DEFINE_TYPE(SndChannelClient, snd_channel_client,
> > > RED_TYPE_CHANNEL_CLIENT)
> > > +static void snd_channel_client_initable_interface_init(GInitableIface
> > > *iface);
> > > +static GInitableIface *snd_channel_client_parent_initable_iface;
> > > +
> > > +G_DEFINE_TYPE_WITH_CODE(SndChannelClient, snd_channel_client,
> > > RED_TYPE_CHANNEL_CLIENT,
> > > +                        G_IMPLEMENT_INTERFACE(G_TYPE_INITABLE,
> > > snd_channel_client_initable_interface_init))
> > >  
> > >  
> > >  enum {
> > > @@ -1083,7 +1087,6 @@ playback_channel_client_constructed(GObject *object)
> > >      if (channel->active) {
> > >          playback_channel_client_start(scc);
> > >      }
> > > -    snd_send(scc);
> > >  }
> > >  
> > >  static void snd_set_peer(RedChannel *red_channel, RedClient *client,
> > >  RedStream *stream,
> > > @@ -1269,7 +1272,6 @@ record_channel_client_constructed(GObject *object)
> > >      if (channel->active) {
> > >          record_channel_client_start(scc);
> > >      }
> > > -    snd_send(scc);
> > >  }
> > >  
> > >  
> > > @@ -1480,6 +1482,35 @@ snd_channel_client_init(SndChannelClient *self)
> > >  {
> > >  }
> > >  
> > > +static gboolean snd_channel_client_initable_init(GInitable *initable,
> > > +                                                 GCancellable
> > > *cancellable,
> > > +                                                 GError **error)
> > > +{
> > > +    gboolean success;
> > > +
> > > +    success = snd_channel_client_parent_initable_iface->init(initable,
> > > cancellable, error);
> > > +    if (!success) {
> > > +        return FALSE;
> > > +    }
> > > +    /* Wait until the very end of the initialization as the channel client
> > > +     * becomes connected (red_channel_client_is_connected() starts
> > > returning
> > > +     * TRUE) only very late in red_channel_client_initable_init()
> > > +     * Before that, red_channel_client_pipe_add() is a no-op because a
> > > connection check is done in
> > > +     * prepare_pipe_add()
> > > +     */
> > > +    snd_send(SND_CHANNEL_CLIENT(initable));
> > > +
> > > +    return TRUE;
> > > +}
> > > +
> > > +static void snd_channel_client_initable_interface_init(GInitableIface
> > > *iface)
> > > +{
> > > +    snd_channel_client_parent_initable_iface =
> > > g_type_interface_peek_parent
> > > (iface);
> > > +
> > > +    iface->init = snd_channel_client_initable_init;
> > > +}
> > > +
> > > +
> > >  static void
> > >  playback_channel_client_class_init(PlaybackChannelClientClass *klass)
> > >  {
> > 
> 
> Testing this, so far is working correctly:
> 
> 
> 
> Subject: [PATCH spice-server] rcc: Make red_channel_client_is_connected return
>  correct information during initialization
> 
> Use stream->watch as flag to check if connected or not initializing
> it during construction, not during init (after all hierarchy is built).
> 
> Signed-off-by: Frediano Ziglio <fziglio at redhat.com>
> ---
>  server/red-channel-client.c | 33 ++++++++++++++++++++++-----------
>  1 file changed, 22 insertions(+), 11 deletions(-)
> 
> diff --git a/server/red-channel-client.c b/server/red-channel-client.c
> index 893a764d..0057108f 100644
> --- a/server/red-channel-client.c
> +++ b/server/red-channel-client.c
> @@ -173,6 +173,7 @@ static void red_channel_client_clear_sent_item(RedChannelClient *rcc);
>  static void red_channel_client_initable_interface_init(GInitableIface *iface);
>  static void red_channel_client_set_message_serial(RedChannelClient *channel, uint64_t);
>  static bool red_channel_client_config_socket(RedChannelClient *rcc);
> +static void red_channel_client_event(int fd, int event, void *data);
>  
>  /*
>   * When an error occurs over a channel, we treat it as a warning
> @@ -293,6 +294,22 @@ red_channel_client_get_property(GObject *object,
>      }
>  }
>  
> +static void
> +red_channel_client_init_watch(RedChannelClient *rcc)
> +{
> +    if (!rcc->priv->stream || rcc->priv->stream->watch || !rcc->priv->channel) {
> +        return;
> +    }
> +
> +    SpiceCoreInterfaceInternal *core = red_channel_get_core_interface(rcc->priv->channel);
> +    red_stream_set_core_interface(rcc->priv->stream, core);
> +    rcc->priv->stream->watch =
> +        core->watch_add(core, rcc->priv->stream->socket,
> +                        SPICE_WATCH_EVENT_READ,
> +                        red_channel_client_event,
> +                        rcc);
> +}
> +
>  static void
>  red_channel_client_set_property(GObject *object,
>                                  guint property_id,
> @@ -305,11 +322,13 @@ red_channel_client_set_property(GObject *object,
>      {
>          case PROP_STREAM:
>              self->priv->stream = g_value_get_pointer(value);
> +            red_channel_client_init_watch(self);
>              break;
>          case PROP_CHANNEL:
>              if (self->priv->channel)
>                  g_object_unref(self->priv->channel);
>              self->priv->channel = g_value_dup_object(value);
> +            red_channel_client_init_watch(self);
>              break;
>          case PROP_CLIENT:
>              self->priv->client = g_value_get_object(value);
> @@ -913,7 +932,6 @@ static gboolean red_channel_client_initable_init(GInitable *initable,
>                                                   GError **error)
>  {
>      GError *local_error = NULL;
> -    SpiceCoreInterfaceInternal *core;
>      RedChannelClient *self = RED_CHANNEL_CLIENT(initable);
>  
>      if (!self->priv->stream) {
> @@ -932,16 +950,10 @@ static gboolean red_channel_client_initable_init(GInitable *initable,
>          goto cleanup;
>      }
>  
> -    core = red_channel_get_core_interface(self->priv->channel);
> -    red_stream_set_core_interface(self->priv->stream, core);
> -    self->priv->stream->watch =
> -        core->watch_add(core, self->priv->stream->socket,
> -                        SPICE_WATCH_EVENT_READ,
> -                        red_channel_client_event,
> -                        self);
> -
>      if (self->priv->monitor_latency
>          && red_stream_get_family(self->priv->stream) != AF_UNIX) {
> +        SpiceCoreInterfaceInternal *core = red_channel_get_core_interface(self->priv->channel);
> +
>          self->priv->latency_monitor.timer =
>              core->timer_add(core, red_channel_client_ping_timer, self);
>  
> @@ -1665,8 +1677,7 @@ bool red_channel_client_is_mini_header(RedChannelClient *rcc)
>  
>  gboolean red_channel_client_is_connected(RedChannelClient *rcc)
>  {
> -    return rcc->priv->channel
> -        && (g_list_find(red_channel_get_clients(rcc->priv->channel), rcc) != NULL);
> +    return rcc->priv->stream->watch != NULL;
>  }
>  
>  static void red_channel_client_clear_sent_item(RedChannelClient *rcc)
> -- 
> 
> 
> Frediano
> _______________________________________________
> Spice-devel mailing list
> Spice-devel at lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/spice-devel
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 833 bytes
Desc: not available
URL: <https://lists.freedesktop.org/archives/spice-devel/attachments/20180524/fa0cf291/attachment-0001.sig>


More information about the Spice-devel mailing list