Max Kellermann <[EMAIL PROTECTED]> wrote:
> Max Kellermann (4):
> const pointers
> tag: fix the shout and oggflac plugins
> oggflac: fix GCC warnings
> tag: optimize tag_dup(), copy item references
>
> audioOutputs/audioOutput_shout.c | 16 +++++++-------
> inputPlugins/oggflac_plugin.c | 24 +++++++++++----------
> tag.c | 12 ++++++----
> tag.h | 8 +++----
> tag_id3.c | 2 -
> tag_id3.h | 2 -
> tag_pool.c | 43
> +++++++++++++++++++++++++++++++++------
> tag_pool.h | 2 +
> 8 files changed, 73 insertions(+), 36 deletions(-)
I'm hitting a segfault when running update, the patch below fixes
things for me.
However I'm thinking the tag_begin_add/tag_end_add() interface is too
fragile and error prone to be worth exposing.
Perhaps make both tag_begin_add and tag_end_add (if busy) get called
implicitly whenever tag_new() is called.
>From 1b48920780d016ac4a93820dd938e51757cc532d Mon Sep 17 00:00:00 2001
From: Eric Wong <[EMAIL PROTECTED]>
Date: Wed, 3 Sep 2008 02:14:52 -0700
Subject: [PATCH] tag: fix segfault on update
clearMpdTag could be called on a tag that was still in a
tag_begin_add transaction before tag_end_add is called. This
was causing free() to attempt to operate on bulk.items; which is
un-free()-able. Now instead we unmark the bulk.busy to avoid
committing the tags to the heap only to be immediately freed.
Additionally, we need to remember to call tag_end_add() when
a song is updated before we NULL song->tag to avoid tripping
an assertion the next time tag_begin_add() is called.
---
src/song.c | 1 +
src/tag.c | 35 +++++++++++++++++++++--------------
2 files changed, 22 insertions(+), 14 deletions(-)
diff --git a/src/song.c b/src/song.c
index 8651a01..067ce44 100644
--- a/src/song.c
+++ b/src/song.c
@@ -202,6 +202,7 @@ static void insertSongIntoList(SongList * list, ListNode **
nextSongNode,
Song *tempSong = (Song *) ((*nextSongNode)->data);
if (tempSong->mtime != song->mtime) {
tag_free(tempSong->tag);
+ tag_end_add(song->tag);
tempSong->tag = song->tag;
tempSong->mtime = song->mtime;
song->tag = NULL;
diff --git a/src/tag.c b/src/tag.c
index d76ba5d..6e31a16 100644
--- a/src/tag.c
+++ b/src/tag.c
@@ -26,6 +26,19 @@
#include "tagTracker.h"
#include "song.h"
+/**
+ * Maximum number of items managed in the bulk list; if it is
+ * exceeded, we switch back to "normal" reallocation.
+ */
+#define BULK_MAX 64
+
+static struct {
+#ifndef NDEBUG
+ int busy;
+#endif
+ struct tag_item *items[BULK_MAX];
+} bulk;
+
const char *mpdTagItemKeys[TAG_NUM_OF_ITEM_TYPES] = {
"Artist",
"Album",
@@ -288,8 +301,15 @@ static void clearMpdTag(struct tag *tag)
tag_pool_put_item(tag->items[i]);
}
- if (tag->items)
+ if (tag->items == bulk.items) {
+#ifndef NDEBUG
+ assert(bulk.busy);
+ bulk.busy = 0;
+#endif
+ } else if (tag->items) {
free(tag->items);
+ }
+
tag->items = NULL;
tag->numOfItems = 0;
@@ -363,19 +383,6 @@ static inline const char *fix_utf8(const char *str, size_t
*length_r) {
return temp;
}
-/**
- * Maximum number of items managed in the bulk list; if it is
- * exceeded, we switch back to "normal" reallocation.
- */
-#define BULK_MAX 64
-
-static struct {
-#ifndef NDEBUG
- int busy;
-#endif
- struct tag_item *items[BULK_MAX];
-} bulk;
-
void tag_begin_add(struct tag *tag)
{
assert(!bulk.busy);
--
Eric Wong
-------------------------------------------------------------------------
This SF.Net email is sponsored by the Moblin Your Move Developer's challenge
Build the coolest Linux based applications with Moblin SDK & win great prizes
Grand prize is a trip for two to an Open Source event anywhere in the world
http://moblin-contest.org/redirect.php?banner_id=100&url=/
_______________________________________________
Musicpd-dev-team mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/musicpd-dev-team