diff options
author | Eric Wong <normalperson@yhbt.net> | 2008-10-03 02:19:54 -0700 |
---|---|---|
committer | Eric Wong <normalperson@yhbt.net> | 2008-10-03 02:19:54 -0700 |
commit | 662b6bc9d75d879e52456f680fb1c4fdd0053996 (patch) | |
tree | 6a839075bd140f7246b54e8e52853b10be614bf1 /src | |
parent | 1d9e9a408798358ea40012adc26eb6e670755337 (diff) | |
download | mpd-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...
Diffstat (limited to '')
-rw-r--r-- | src/song.c | 21 |
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; |