[Spice-devel] [spice-server] sound: Don't mute recording when client reconnects
Christophe Fergeau
cfergeau at redhat.com
Wed May 23 10:16:15 UTC 2018
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
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.
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)
{
--
2.17.0
More information about the Spice-devel
mailing list