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
Musicpd-dev-team@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/musicpd-dev-team

Reply via email to