aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEric Wong <normalperson@yhbt.net>2008-10-03 02:19:54 -0700
committerEric Wong <normalperson@yhbt.net>2008-10-03 02:19:54 -0700
commit662b6bc9d75d879e52456f680fb1c4fdd0053996 (patch)
tree6a839075bd140f7246b54e8e52853b10be614bf1
parent1d9e9a408798358ea40012adc26eb6e670755337 (diff)
downloadmpd-662b6bc9d75d879e52456f680fb1c4fdd0053996.tar.gz
mpd-662b6bc9d75d879e52456f680fb1c4fdd0053996.tar.xz
mpd-662b6bc9d75d879e52456f680fb1c4fdd0053996.zip
song: start avoiding race in updateSongInfo
This is still not SMP-safe yet, as it needs at least a barrier before calling tag_free(old_tag). Locks may be simpler to implement and the potential performance gain of avoiding locks may not be worth it on infrequently modified data structures...
-rw-r--r--src/song.c21
1 files changed, 12 insertions, 9 deletions
diff --git a/src/song.c b/src/song.c
index 5c5024391..dc100899a 100644
--- a/src/song.c
+++ b/src/song.c
@@ -207,19 +207,22 @@ int updateSongInfo(Song * song)
unsigned int next = 0;
char path_max_tmp[MPD_PATH_MAX];
char abs_path[MPD_PATH_MAX];
+ struct mpd_tag *old_tag = song->tag;
+ struct mpd_tag *new_tag = NULL;
utf8_to_fs_charset(abs_path, get_song_url(path_max_tmp, song));
rmp2amp_r(abs_path, abs_path);
- if (song->tag)
- tag_free(song->tag);
-
- song->tag = NULL;
-
- while (!song->tag && (plugin = isMusic(abs_path,
- &(song->mtime),
- next++))) {
- song->tag = plugin->tagDupFunc(abs_path);
+ while ((plugin = isMusic(abs_path, &song->mtime, next++))) {
+ if ((new_tag = plugin->tagDupFunc(abs_path)))
+ break;
+ }
+ if (new_tag && tag_equal(new_tag, old_tag)) {
+ tag_free(new_tag);
+ } else {
+ song->tag = new_tag;
+ if (old_tag)
+ tag_free(old_tag);
}
if (!song->tag || song->tag->time < 0)
return -1;