[Spice-commits] 9 commits - gtk/channel-playback.c gtk/channel-record.c gtk/channel-webdav.c gtk/spice-audio.c gtk/spice-gstaudio.c gtk/spice-pulse.c gtk/spice-session.c gtk/usb-device-manager.c

Marc-André Lureau elmarco at kemper.freedesktop.org
Thu May 7 12:50:57 PDT 2015


 gtk/channel-playback.c   |   12 ++++++++++--
 gtk/channel-record.c     |   13 ++++++++++---
 gtk/channel-webdav.c     |    7 ++++---
 gtk/spice-audio.c        |    2 +-
 gtk/spice-gstaudio.c     |    9 +++++----
 gtk/spice-pulse.c        |    7 ++++---
 gtk/spice-session.c      |    7 +++++--
 gtk/usb-device-manager.c |    3 +--
 8 files changed, 40 insertions(+), 20 deletions(-)

New commits:
commit 05c6088d1dacef8a48554d4954c40f6612adb35c
Author: Marc-André Lureau <marcandre.lureau at redhat.com>
Date:   Wed May 6 17:56:49 2015 +0200

    webdav: check g_output_stream_write_all() return value
    
    Check g_output_stream_write_all() return value to silence a coverity
    CHECKED_RETURN warning

diff --git a/gtk/channel-webdav.c b/gtk/channel-webdav.c
index 95c0521..1d3862e 100644
--- a/gtk/channel-webdav.c
+++ b/gtk/channel-webdav.c
@@ -147,8 +147,7 @@ static gboolean output_queue_idle(gpointer user_data)
         return FALSE;
     }
 
-    g_output_stream_write_all(q->output, e->buf, e->size, NULL, NULL, &error);
-    if (error)
+    if (!g_output_stream_write_all(q->output, e->buf, e->size, NULL, NULL, &error))
         goto err;
     else if (e->pushed_cb)
         e->pushed_cb(q, e->user_data);
@@ -159,7 +158,9 @@ static gboolean output_queue_idle(gpointer user_data)
     return TRUE;
 
 err:
-    g_warning("error: %s", error->message);
+    g_warning("failed to write to output stream");
+    if (error)
+        g_warning("error: %s", error->message);
     g_clear_error(&error);
 
     q->idle_id = 0;
commit 9546b571d7143e4c9efcb022d6016ea1c9ed2536
Author: Marc-André Lureau <marcandre.lureau at redhat.com>
Date:   Tue Apr 28 14:30:28 2015 +0200

    usb: channel-new handler to be after default handlers
    
    Client usually connect to channel-new to connect their
    handlers, such as open-fd.
    
    The usbmanager channel-new handler will call channel_connect() on usbredir
    channels, which may call open-fd.
    
    However, open-fd can be emitted before the client had a chance to
    connect their handlers (from the channel-new callback).
    
    Connecting after the default handler solves this case.
    
    Fixes:
    https://bugzilla.gnome.org/show_bug.cgi?id=748665

diff --git a/gtk/usb-device-manager.c b/gtk/usb-device-manager.c
index e11eae0..7aa60c4 100644
--- a/gtk/usb-device-manager.c
+++ b/gtk/usb-device-manager.c
@@ -310,8 +310,7 @@ static gboolean spice_usb_device_manager_initable_init(GInitable  *initable,
 #endif
 
     /* Start listening for usb channels connect/disconnect */
-    g_signal_connect(priv->session, "channel-new",
-                     G_CALLBACK(channel_new), self);
+    spice_g_signal_connect_object(priv->session, "channel-new", G_CALLBACK(channel_new), self, G_CONNECT_AFTER);
     g_signal_connect(priv->session, "channel-destroy",
                      G_CALLBACK(channel_destroy), self);
     list = spice_session_get_channels(priv->session);
commit f11f5b2a27ed6ec3c5b1cec8f7d1bc4112705c2c
Author: Marc-André Lureau <marcandre.lureau at redhat.com>
Date:   Wed Apr 29 20:59:48 2015 +0200

    session: do not attempt to open_host if session changed
    
    Since channel can become session-less, let's check they still have the
    expected session when running the open-host idle.

diff --git a/gtk/spice-session.c b/gtk/spice-session.c
index 020a70e..52fa394 100644
--- a/gtk/spice-session.c
+++ b/gtk/spice-session.c
@@ -2027,12 +2027,15 @@ static void proxy_lookup_ready(GObject *source_object, GAsyncResult *result,
 static gboolean open_host_idle_cb(gpointer data)
 {
     spice_open_host *open_host = data;
-    SpiceSession *session = open_host->session;
-    SpiceSessionPrivate *s = session->priv;
+    SpiceSessionPrivate *s;
 
     g_return_val_if_fail(open_host != NULL, FALSE);
     g_return_val_if_fail(open_host->connection == NULL, FALSE);
 
+    if (spice_channel_get_session(open_host->channel) != open_host->session)
+        return FALSE;
+
+    s = open_host->session->priv;
     open_host->proxy = s->proxy;
     if (open_host->error != NULL) {
         coroutine_yieldto(open_host->from, NULL);
commit b8ffe53d67f0b3f5b3e1ea0ba16e757aea5780fb
Author: Marc-André Lureau <marcandre.lureau at redhat.com>
Date:   Wed Apr 29 17:00:00 2015 +0200

    audio: stop playback on channel destroyed
    
    Ensure playback is stopped when the channel is destroyed.

diff --git a/gtk/spice-gstaudio.c b/gtk/spice-gstaudio.c
index 3bdf23e..99d12b1 100644
--- a/gtk/spice-gstaudio.c
+++ b/gtk/spice-gstaudio.c
@@ -494,6 +494,8 @@ channel_weak_notified(gpointer data,
     SpiceGstaudioPrivate *p = gstaudio->priv;
 
     if (where_the_object_was == (GObject *)p->pchannel) {
+        SPICE_DEBUG("playback closed");
+        playback_stop(gstaudio);
         p->pchannel = NULL;
     } else if (where_the_object_was == (GObject *)p->rchannel) {
         SPICE_DEBUG("record closed");
diff --git a/gtk/spice-pulse.c b/gtk/spice-pulse.c
index 2373c72..22db893 100644
--- a/gtk/spice-pulse.c
+++ b/gtk/spice-pulse.c
@@ -776,6 +776,8 @@ channel_weak_notified(gpointer data,
     SpicePulsePrivate *p = pulse->priv;
 
     if (where_the_object_was == (GObject *)p->pchannel) {
+        SPICE_DEBUG("playback closed");
+        playback_stop(pulse);
         p->pchannel = NULL;
     } else if (where_the_object_was == (GObject *)p->rchannel) {
         SPICE_DEBUG("record closed");
commit 63bf00275769928850113b4df205df08d6303b45
Author: Marc-André Lureau <marcandre.lureau at redhat.com>
Date:   Wed Apr 29 16:52:46 2015 +0200

    audio: use swapped channel handler for stop
    
    We are going to reuse playback_stop() in following commit.

diff --git a/gtk/spice-gstaudio.c b/gtk/spice-gstaudio.c
index 936aa5b..3bdf23e 100644
--- a/gtk/spice-gstaudio.c
+++ b/gtk/spice-gstaudio.c
@@ -257,9 +257,8 @@ cleanup:
         gst_element_set_state(p->record.pipe, GST_STATE_PLAYING);
 }
 
-static void playback_stop(SpicePlaybackChannel *channel, gpointer data)
+static void playback_stop(SpiceGstaudio *gstaudio)
 {
-    SpiceGstaudio *gstaudio = data;
     SpiceGstaudioPrivate *p = gstaudio->priv;
 
     if (p->playback.pipe)
@@ -303,7 +302,7 @@ static void playback_start(SpicePlaybackChannel *channel, gint format, gint chan
     if (p->playback.pipe &&
         (p->playback.rate != frequency ||
          p->playback.channels != channels)) {
-        playback_stop(channel, data);
+        playback_stop(gstaudio);
         gst_object_unref(p->playback.pipe);
         p->playback.pipe = NULL;
     }
@@ -518,7 +517,7 @@ static gboolean connect_channel(SpiceAudio *audio, SpiceChannel *channel)
         spice_g_signal_connect_object(channel, "playback-data",
                                       G_CALLBACK(playback_data), gstaudio, 0);
         spice_g_signal_connect_object(channel, "playback-stop",
-                                      G_CALLBACK(playback_stop), gstaudio, 0);
+                                      G_CALLBACK(playback_stop), gstaudio, G_CONNECT_SWAPPED);
         spice_g_signal_connect_object(channel, "notify::volume",
                                       G_CALLBACK(playback_volume_changed), gstaudio, 0);
         spice_g_signal_connect_object(channel, "notify::mute",
diff --git a/gtk/spice-pulse.c b/gtk/spice-pulse.c
index 916f1d0..2373c72 100644
--- a/gtk/spice-pulse.c
+++ b/gtk/spice-pulse.c
@@ -489,9 +489,8 @@ static void playback_data(SpicePlaybackChannel *channel,
     p->playback.state = state;
 }
 
-static void playback_stop(SpicePlaybackChannel *channel, gpointer data)
+static void playback_stop(SpicePulse *pulse)
 {
-    SpicePulse *pulse = data;
     SpicePulsePrivate *p = pulse->priv;
 
     SPICE_DEBUG("%s: #underflow %u", __FUNCTION__, p->playback.num_underflow);
@@ -800,7 +799,7 @@ static gboolean connect_channel(SpiceAudio *audio, SpiceChannel *channel)
         spice_g_signal_connect_object(channel, "playback-data",
                                       G_CALLBACK(playback_data), pulse, 0);
         spice_g_signal_connect_object(channel, "playback-stop",
-                                      G_CALLBACK(playback_stop), pulse, 0);
+                                      G_CALLBACK(playback_stop), pulse, G_CONNECT_SWAPPED);
         spice_g_signal_connect_object(channel, "notify::volume",
                                       G_CALLBACK(playback_volume_changed), pulse, 0);
         spice_g_signal_connect_object(channel, "notify::mute",
commit 4a9e4622b159aea54949b62f4a1dde1416cfa251
Author: Marc-André Lureau <marcandre.lureau at redhat.com>
Date:   Wed Apr 29 16:19:57 2015 +0200

    record: do not crash after record is stopped
    
    If spice_record_send_data() after a reset, last_frame is NULL and memcpy
    will crash.  Check if the recording was started if last_frame != NULL
    instead.
    
     Program received signal SIGSEGV, Segmentation fault.
     __memcpy_avx_unaligned () at ../sysdeps/x86_64/multiarch/memcpy-avx-unaligned.S:204
     204                       vmovdqa %ymm0, (%rdi)
     (gdb) bt
     #0  __memcpy_avx_unaligned () at ../sysdeps/x86_64/multiarch/memcpy-avx-unaligned.S:204
     #1  0x00007ffff44f57b5 in spice_record_send_data (channel=0x1228640, data=0x7fff9ad0f000, bytes=960, time=0) at channel-record.c:349
     #2  0x00007ffff45162f0 in stream_read_callback (s=0xad8c00, length=960, data=<optimized out>) at spice-pulse.c:485
     #3  0x00007ffff2ea0c76 in pstream_memblock_callback (p=<optimized out>, channel=<optimized out>, offset=0, seek=PA_SEEK_RELATIVE, chunk=0x7fffffffcf70, userdata=0x11e71c0) at pulse/context.c:411
     #4  0x00007fffe8da8b4f in do_read (p=p at entry=0x123a050, re=re at entry=0x123a1d0) at pulsecore/pstream.c:906
     #5  0x00007fffe8daae87 in do_pstream_read_write (p=0x123a050) at pulsecore/pstream.c:193
     #6  0x00007ffff30e1bea in dispatch_func (source=0x1111e50, callback=<optimized out>, userdata=<optimized out>) at pulse/glib-mainloop.c:584
     #7  0x00007fffed76b93b in g_main_dispatch (context=0x816ea0) at gmain.c:3122
    
    Fixes:
    https://bugzilla.redhat.com/show_bug.cgi?id=1215343

diff --git a/gtk/channel-record.c b/gtk/channel-record.c
index 0b41349..d07d84e 100644
--- a/gtk/channel-record.c
+++ b/gtk/channel-record.c
@@ -322,13 +322,17 @@ void spice_record_send_data(SpiceRecordChannel *channel, gpointer data,
     SpiceRecordChannelPrivate *rc;
     SpiceMsgcRecordPacket p = {0, };
 
-    g_return_if_fail(channel != NULL);
+    g_return_if_fail(SPICE_IS_RECORD_CHANNEL(channel));
+    rc = channel->priv;
+    if (rc->last_frame == NULL) {
+        CHANNEL_DEBUG(channel, "recording didn't start or was reset");
+        return;
+    }
+
     g_return_if_fail(spice_channel_get_read_only(SPICE_CHANNEL(channel)) == FALSE);
 
     uint8_t *encode_buf = NULL;
 
-    rc = channel->priv;
-
     if (!rc->started) {
         spice_record_mode(channel, time, rc->mode, NULL, 0);
         spice_record_start_mark(channel, time);
commit 8edd8b06c1be4fc45d2370ca287421674f090d22
Author: Marc-André Lureau <marcandre.lureau at redhat.com>
Date:   Wed Apr 29 16:16:35 2015 +0200

    playback: do not set mm time when session-less
    
    Channels do not hold a strong reference on the session (because session
    can be recycled after disconnect), do not print a warning if the channel
    is session-less when updating the delay.

diff --git a/gtk/channel-playback.c b/gtk/channel-playback.c
index 9d45e1f..d8a181e 100644
--- a/gtk/channel-playback.c
+++ b/gtk/channel-playback.c
@@ -452,6 +452,7 @@ static void channel_set_handlers(SpiceChannelClass *klass)
 void spice_playback_channel_set_delay(SpicePlaybackChannel *channel, guint32 delay_ms)
 {
     SpicePlaybackChannelPrivate *c;
+    SpiceSession *session;
 
     g_return_if_fail(SPICE_IS_PLAYBACK_CHANNEL(channel));
 
@@ -459,8 +460,13 @@ void spice_playback_channel_set_delay(SpicePlaybackChannel *channel, guint32 del
 
     c = channel->priv;
     c->latency = delay_ms;
-    spice_session_set_mm_time(spice_channel_get_session(SPICE_CHANNEL(channel)),
-                              c->last_time - delay_ms);
+
+    session = spice_channel_get_session(SPICE_CHANNEL(channel));
+    if (session) {
+        spice_session_set_mm_time(session, c->last_time - delay_ms);
+    } else {
+        CHANNEL_DEBUG(channel, "channel detached from session, mm time skipped");
+    }
 }
 
 G_GNUC_INTERNAL
commit 1d0a91d5ea7eb239d24fa58da4756fdac1b0155b
Author: Marc-André Lureau <marcandre.lureau at redhat.com>
Date:   Wed Apr 29 16:08:37 2015 +0200

    audio: emit stop when the channels are reset
    
    Ensure a hint is given to the client that the channel is reset.
    
    Unfortunately, since the handle may be asynchronous due to coroutine,
    the channel functions should be tolerant to a playback/record calls
    functions when the channel is stopped.

diff --git a/gtk/channel-playback.c b/gtk/channel-playback.c
index ae8a75d..9d45e1f 100644
--- a/gtk/channel-playback.c
+++ b/gtk/channel-playback.c
@@ -172,6 +172,8 @@ static void spice_playback_channel_reset(SpiceChannel *channel, gboolean migrati
     SpicePlaybackChannelPrivate *c = SPICE_PLAYBACK_CHANNEL(channel)->priv;
 
     snd_codec_destroy(&c->codec);
+    g_coroutine_signal_emit(channel, signals[SPICE_PLAYBACK_STOP], 0);
+    c->is_active = FALSE;
 
     SPICE_CHANNEL_CLASS(spice_playback_channel_parent_class)->channel_reset(channel, migrating);
 }
diff --git a/gtk/channel-record.c b/gtk/channel-record.c
index ac71999..0b41349 100644
--- a/gtk/channel-record.c
+++ b/gtk/channel-record.c
@@ -169,6 +169,9 @@ static void channel_reset(SpiceChannel *channel, gboolean migrating)
     g_free(c->last_frame);
     c->last_frame = NULL;
 
+    g_coroutine_signal_emit(channel, signals[SPICE_RECORD_STOP], 0);
+    c->started = FALSE;
+
     snd_codec_destroy(&c->codec);
 
     SPICE_CHANNEL_CLASS(spice_record_channel_parent_class)->channel_reset(channel, migrating);
commit 81d8175d9d6a8297b10cead6c951bf560f61be4c
Author: Marc-André Lureau <marcandre.lureau at redhat.com>
Date:   Tue Apr 28 14:30:28 2015 +0200

    audio: channel-new handler to be after default handlers
    
    Client usually connect to channel-new to connect their
    handlers, such as open-fd.
    
    The audio channel-new handler will call channel_connect() on audio
    channels, which may call open-fd.
    
    However, open-fd can be emitted before the client had a chance to
    connect their handlers (from the channel-new callback).
    
    Connecting after the default handler solves this case.
    
    Fixes:
    https://bugzilla.gnome.org/show_bug.cgi?id=747649

diff --git a/gtk/spice-audio.c b/gtk/spice-audio.c
index 7784c8b..ce191e1 100644
--- a/gtk/spice-audio.c
+++ b/gtk/spice-audio.c
@@ -267,7 +267,7 @@ SpiceAudio *spice_audio_new(SpiceSession *session, GMainContext *context,
         return NULL;
 
     spice_g_signal_connect_object(session, "notify::enable-audio", G_CALLBACK(session_enable_audio), self, 0);
-    spice_g_signal_connect_object(session, "channel-new", G_CALLBACK(channel_new), self, 0);
+    spice_g_signal_connect_object(session, "channel-new", G_CALLBACK(channel_new), self, G_CONNECT_AFTER);
     update_audio_channels(self, session);
 
     return self;


More information about the Spice-commits mailing list