[Spice-commits] 2 commits - server/snd_worker.c
Christophe Fergau
teuf at kemper.freedesktop.org
Mon Oct 1 10:13:33 PDT 2012
server/snd_worker.c | 18 ++++++++++++------
1 file changed, 12 insertions(+), 6 deletions(-)
New commits:
commit d958fc100c0d14c8f55016df417c7587f670b037
Author: Andrew Eikum <aeikum at codeweavers.com>
Date: Thu Sep 13 13:38:50 2012 -0500
server: Access the correct SndChannel for a given AudioFrame
The client of _get_buffer() holds a ref to the SndChannel, and we
should access that SndChannel when _put_samples() is called, not the one
that happens to currently be attached to the Interface.
diff --git a/server/snd_worker.c b/server/snd_worker.c
index 13f8c4d..6034aec 100644
--- a/server/snd_worker.c
+++ b/server/snd_worker.c
@@ -122,10 +122,14 @@ struct SndChannel {
snd_channel_cleanup_channel_proc cleanup;
};
+struct PlaybackChannel;
+typedef struct PlaybackChannel PlaybackChannel;
+
typedef struct AudioFrame AudioFrame;
struct AudioFrame {
uint32_t time;
uint32_t samples[FRAME_SIZE];
+ PlaybackChannel *channel;
AudioFrame *next;
};
@@ -227,6 +231,7 @@ static void snd_disconnect_channel(SndChannel *channel)
static void snd_playback_free_frame(PlaybackChannel *playback_channel, AudioFrame *frame)
{
+ frame->channel = playback_channel;
frame->next = playback_channel->free_frames;
playback_channel->free_frames = frame;
}
@@ -1067,14 +1072,16 @@ SPICE_GNUC_VISIBLE void spice_server_playback_get_buffer(SpicePlaybackInstance *
SPICE_GNUC_VISIBLE void spice_server_playback_put_samples(SpicePlaybackInstance *sin, uint32_t *samples)
{
- SndChannel *channel = sin->st->worker.connection;
- PlaybackChannel *playback_channel = SPICE_CONTAINEROF(channel, PlaybackChannel, base);
+ PlaybackChannel *playback_channel;
AudioFrame *frame;
- if (!channel) {
+ if (!sin->st->worker.connection) {
return;
}
- if (!snd_channel_put(channel)) {
+
+ frame = SPICE_CONTAINEROF(samples, AudioFrame, samples);
+ playback_channel = frame->channel;
+ if (!snd_channel_put(&playback_channel->base) || !playback_channel->base.worker->connection) {
/* lost last reference, channel has been destroyed previously */
return;
}
@@ -1083,7 +1090,6 @@ SPICE_GNUC_VISIBLE void spice_server_playback_put_samples(SpicePlaybackInstance
if (playback_channel->pending_frame) {
snd_playback_free_frame(playback_channel, playback_channel->pending_frame);
}
- frame = SPICE_CONTAINEROF(samples, AudioFrame, samples);
frame->time = reds_get_mm_time();
red_dispatcher_set_mm_time(frame->time);
playback_channel->pending_frame = frame;
commit 0a62e332119abf5d21790e125f51c599a5c651dd
Author: Andrew Eikum <aeikum at codeweavers.com>
Date: Thu Sep 13 13:21:07 2012 -0500
server: Don't release SndChannel twice from worker reference
When we release the SndChannel reference during
snd_disconnect_channel(), we need to set the pointer to NULL so it
doesn't get released again on client reconnect during
snd_set_playback_peer(). This can happen when a reference is held from
_playback_get_buffer().
diff --git a/server/snd_worker.c b/server/snd_worker.c
index 995823c..13f8c4d 100644
--- a/server/snd_worker.c
+++ b/server/snd_worker.c
@@ -195,7 +195,6 @@ static SndChannel *snd_channel_get(SndChannel *channel)
static SndChannel *snd_channel_put(SndChannel *channel)
{
if (!--channel->refs) {
- channel->worker->connection = NULL;
free(channel);
spice_printerr("sound channel freed");
return NULL;
@@ -223,6 +222,7 @@ static void snd_disconnect_channel(SndChannel *channel)
spice_marshaller_destroy(channel->send_data.marshaller);
}
snd_channel_put(channel);
+ channel->worker->connection = NULL;
}
static void snd_playback_free_frame(PlaybackChannel *playback_channel, AudioFrame *frame)
More information about the Spice-commits
mailing list