aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorMax Kellermann <max@duempel.org>2012-08-09 20:55:18 +0200
committerMax Kellermann <max@duempel.org>2012-08-15 23:08:39 +0200
commiteb54337c40cbedc79177b48d2feaea9d12e95c0f (patch)
tree605176f21d8784541ea1965e4be7b7a2dcf6f4a3 /src
parent916a02017333ac32b8058d3c397eeb4ec85b742b (diff)
downloadmpd-eb54337c40cbedc79177b48d2feaea9d12e95c0f.tar.gz
mpd-eb54337c40cbedc79177b48d2feaea9d12e95c0f.tar.xz
mpd-eb54337c40cbedc79177b48d2feaea9d12e95c0f.zip
decoder_control: duplicate the song object
Make sure the decoder "owns" the song object, so nobody else can free it.
Diffstat (limited to 'src')
-rw-r--r--src/decoder_control.c8
-rw-r--r--src/decoder_control.h8
-rw-r--r--src/player_thread.c2
3 files changed, 15 insertions, 3 deletions
diff --git a/src/decoder_control.c b/src/decoder_control.c
index 8bf21365c..afcb16cdf 100644
--- a/src/decoder_control.c
+++ b/src/decoder_control.c
@@ -41,6 +41,8 @@ dc_new(GCond *client_cond)
dc->state = DECODE_STATE_STOP;
dc->command = DECODE_COMMAND_NONE;
+ dc->song = NULL;
+
dc->replay_gain_db = 0;
dc->replay_gain_prev_db = 0;
dc->mixramp_start = NULL;
@@ -55,6 +57,9 @@ dc_free(struct decoder_control *dc)
{
dc_clear_error(dc);
+ if (dc->song != NULL)
+ song_free(dc->song);
+
g_cond_free(dc->cond);
g_mutex_free(dc->mutex);
g_free(dc->mixramp_start);
@@ -129,6 +134,9 @@ dc_start(struct decoder_control *dc, struct song *song,
assert(pipe != NULL);
assert(music_pipe_empty(pipe));
+ if (dc->song != NULL)
+ song_free(dc->song);
+
dc->song = song;
dc->start_ms = start_ms;
dc->end_ms = end_ms;
diff --git a/src/decoder_control.h b/src/decoder_control.h
index 7305e5813..9ecbde73e 100644
--- a/src/decoder_control.h
+++ b/src/decoder_control.h
@@ -90,8 +90,11 @@ struct decoder_control {
* The song currently being decoded. This attribute is set by
* the player thread, when it sends the #DECODE_COMMAND_START
* command.
+ *
+ * This is a duplicate, and must be freed when this attribute
+ * is cleared.
*/
- const struct song *song;
+ struct song *song;
/**
* The initial seek position (in milliseconds), e.g. to the
@@ -303,7 +306,8 @@ decoder_lock_is_current_song(struct decoder_control *dc,
* Start the decoder.
*
* @param the decoder
- * @param song the song to be decoded
+ * @param song the song to be decoded; the given instance will be
+ * owned and freed by the decoder
* @param start_ms see #decoder_control
* @param end_ms see #decoder_control
* @param pipe the pipe which receives the decoded chunks (owned by
diff --git a/src/player_thread.c b/src/player_thread.c
index cf0b9ac8d..1f48df66b 100644
--- a/src/player_thread.c
+++ b/src/player_thread.c
@@ -162,7 +162,7 @@ player_dc_start(struct player *player, struct music_pipe *pipe)
if (pc->command == PLAYER_COMMAND_SEEK)
start_ms += (unsigned)(pc->seek_where * 1000);
- dc_start(dc, pc->next_song,
+ dc_start(dc, song_dup_detached(pc->next_song),
start_ms, pc->next_song->end_ms,
player_buffer, pipe);
}