From bb097109f0d3cc8d7b2fc91a8196d7975022b104 Mon Sep 17 00:00:00 2001 From: Max Kellermann Date: Fri, 27 Jan 2017 08:47:36 +0100 Subject: [PATCH 1/9] configure.ac: prepare for 0.20.4 --- NEWS | 2 ++ configure.ac | 4 ++-- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/NEWS b/NEWS index 3824466ac..49b8568d9 100644 --- a/NEWS +++ b/NEWS @@ -1,3 +1,5 @@ +ver 0.20.4 (not yet released) + ver 0.20.3 (2017/01/25) * protocol - "playlistadd" creates new playlist if it does not exist, as documented diff --git a/configure.ac b/configure.ac index a273f8bd9..b18d89d2e 100644 --- a/configure.ac +++ b/configure.ac @@ -1,10 +1,10 @@ AC_PREREQ(2.60) -AC_INIT(mpd, 0.20.3, musicpd-dev-team@lists.sourceforge.net) +AC_INIT(mpd, 0.20.4, musicpd-dev-team@lists.sourceforge.net) VERSION_MAJOR=0 VERSION_MINOR=20 -VERSION_REVISION=3 +VERSION_REVISION=4 VERSION_EXTRA=0 AC_CONFIG_SRCDIR([src/Main.cxx]) From 5bd322bdcf960bc551e05ccc0f934c1031ce6bad Mon Sep 17 00:00:00 2001 From: Max Kellermann Date: Fri, 27 Jan 2017 08:47:58 +0100 Subject: [PATCH 2/9] python/libs: upgrade Opus to 1.1.4 --- python/build/libs.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/python/build/libs.py b/python/build/libs.py index 68beb78c6..54f292578 100644 --- a/python/build/libs.py +++ b/python/build/libs.py @@ -19,8 +19,8 @@ libvorbis = AutotoolsProject( ) opus = AutotoolsProject( - 'http://downloads.xiph.org/releases/opus/opus-1.1.3.tar.gz', - '32bbb6b557fe1b6066adc0ae1f08b629', + 'http://downloads.xiph.org/releases/opus/opus-1.1.4.tar.gz', + '9122b6b380081dd2665189f97bfd777f04f92dc3ab6698eea1dbb27ad59d8692', 'lib/libopus.a', ['--disable-shared', '--enable-static'], ) From a9316863176f2e66f78b050b772fe87af3462f2c Mon Sep 17 00:00:00 2001 From: Max Kellermann Date: Fri, 27 Jan 2017 11:02:58 +0100 Subject: [PATCH 3/9] pcm/SampleFormat: workaround for GCC 4.9 "constexpr" bug GCC 4.9 has incomplete C++14 support. Specifically, it doesn't allow switch/case in "constexpr" functions. --- NEWS | 1 + src/pcm/SampleFormat.hxx | 10 ++++++++-- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/NEWS b/NEWS index 49b8568d9..5801b90bd 100644 --- a/NEWS +++ b/NEWS @@ -1,4 +1,5 @@ ver 0.20.4 (not yet released) +* workaround for GCC 4.9 "constexpr" bug ver 0.20.3 (2017/01/25) * protocol diff --git a/src/pcm/SampleFormat.hxx b/src/pcm/SampleFormat.hxx index 25e6352b6..9ac2c8dab 100644 --- a/src/pcm/SampleFormat.hxx +++ b/src/pcm/SampleFormat.hxx @@ -64,7 +64,10 @@ enum class SampleFormat : uint8_t { /** * Checks whether the sample format is valid. */ -static constexpr inline bool +#if !GCC_OLDER_THAN(5,0) +constexpr +#endif +static inline bool audio_valid_sample_format(SampleFormat format) { switch (format) { @@ -83,7 +86,10 @@ audio_valid_sample_format(SampleFormat format) return false; } -static constexpr inline unsigned +#if !GCC_OLDER_THAN(5,0) +constexpr +#endif +static inline unsigned sample_format_size(SampleFormat format) { switch (format) { From 51147203be4848847f079847206c9b5e0e36cb3d Mon Sep 17 00:00:00 2001 From: Thomas Zander Date: Sat, 28 Jan 2017 16:07:37 +0100 Subject: [PATCH 4/9] free() require cstdlib to be included --- NEWS | 1 + src/util/VarSize.hxx | 1 + 2 files changed, 2 insertions(+) diff --git a/NEWS b/NEWS index 5801b90bd..fb9111ead 100644 --- a/NEWS +++ b/NEWS @@ -1,5 +1,6 @@ ver 0.20.4 (not yet released) * workaround for GCC 4.9 "constexpr" bug +* fix FreeBSD build failure ver 0.20.3 (2017/01/25) * protocol diff --git a/src/util/VarSize.hxx b/src/util/VarSize.hxx index a386e5dc4..5f383bc4b 100644 --- a/src/util/VarSize.hxx +++ b/src/util/VarSize.hxx @@ -36,6 +36,7 @@ #include #include #include +#include /** * Allocate and construct a variable-size object. That is useful for From f71c204eef0149c25951597f5c4235cbfcac981c Mon Sep 17 00:00:00 2001 From: Thomas Zander Date: Sat, 28 Jan 2017 16:12:30 +0100 Subject: [PATCH 5/9] Correct method types to match Interface.hxx --- src/db/Count.cxx | 8 ++------ src/db/DatabasePlaylist.cxx | 3 +-- src/db/DatabasePrint.cxx | 31 ++++++++----------------------- src/db/DatabaseQueue.cxx | 3 +-- src/db/Helpers.cxx | 4 +--- 5 files changed, 13 insertions(+), 36 deletions(-) diff --git a/src/db/Count.cxx b/src/db/Count.cxx index ddd9e2930..9c3945677 100644 --- a/src/db/Count.cxx +++ b/src/db/Count.cxx @@ -62,7 +62,7 @@ Print(Response &r, TagType group, const TagCountMap &m) } } -static bool +static void stats_visitor_song(SearchStats &stats, const LightSong &song) { stats.n_songs++; @@ -70,8 +70,6 @@ stats_visitor_song(SearchStats &stats, const LightSong &song) const auto duration = song.GetDuration(); if (!duration.IsNegative()) stats.total_duration += duration; - - return true; } static bool @@ -94,7 +92,7 @@ CollectGroupCounts(TagCountMap &map, TagType group, const Tag &tag) return found; } -static bool +static void GroupCountVisitor(TagCountMap &map, TagType group, const LightSong &song) { assert(song.tag != nullptr); @@ -103,8 +101,6 @@ GroupCountVisitor(TagCountMap &map, TagType group, const LightSong &song) if (!CollectGroupCounts(map, group, tag) && group == TAG_ALBUM_ARTIST) /* fall back to "Artist" if no "AlbumArtist" was found */ CollectGroupCounts(map, TAG_ARTIST, tag); - - return true; } void diff --git a/src/db/DatabasePlaylist.cxx b/src/db/DatabasePlaylist.cxx index b19895b96..78bbdd5cd 100644 --- a/src/db/DatabasePlaylist.cxx +++ b/src/db/DatabasePlaylist.cxx @@ -27,13 +27,12 @@ #include -static bool +static void AddSong(const Storage &storage, const char *playlist_path_utf8, const LightSong &song) { spl_append_song(playlist_path_utf8, DatabaseDetachSong(storage, song)); - return true; } void diff --git a/src/db/DatabasePrint.cxx b/src/db/DatabasePrint.cxx index 8435748fa..87d441d20 100644 --- a/src/db/DatabasePrint.cxx +++ b/src/db/DatabasePrint.cxx @@ -49,16 +49,14 @@ PrintDirectoryURI(Response &r, bool base, const LightDirectory &directory) ApplyBaseFlag(directory.GetPath(), base)); } -static bool +static void PrintDirectoryBrief(Response &r, bool base, const LightDirectory &directory) { if (!directory.IsRoot()) PrintDirectoryURI(r, base, directory); - - return true; } -static bool +static void PrintDirectoryFull(Response &r, bool base, const LightDirectory &directory) { if (!directory.IsRoot()) { @@ -67,8 +65,6 @@ PrintDirectoryFull(Response &r, bool base, const LightDirectory &directory) if (directory.mtime > 0) time_print(r, "Last-Modified", directory.mtime); } - - return true; } static void @@ -96,7 +92,7 @@ print_playlist_in_directory(Response &r, bool base, directory->GetPath(), name_utf8); } -static bool +static void PrintSongBrief(Response &r, Partition &partition, bool base, const LightSong &song) { @@ -106,11 +102,9 @@ PrintSongBrief(Response &r, Partition &partition, /* this song file has an embedded CUE sheet */ print_playlist_in_directory(r, base, song.directory, song.uri); - - return true; } -static bool +static void PrintSongFull(Response &r, Partition &partition, bool base, const LightSong &song) { @@ -120,21 +114,18 @@ PrintSongFull(Response &r, Partition &partition, /* this song file has an embedded CUE sheet */ print_playlist_in_directory(r, base, song.directory, song.uri); - - return true; } -static bool +static void PrintPlaylistBrief(Response &r, bool base, const PlaylistInfo &playlist, const LightDirectory &directory) { print_playlist_in_directory(r, base, &directory, playlist.name.c_str()); - return true; } -static bool +static void PrintPlaylistFull(Response &r, bool base, const PlaylistInfo &playlist, const LightDirectory &directory) @@ -144,8 +135,6 @@ PrintPlaylistFull(Response &r, bool base, if (playlist.mtime > 0) time_print(r, "Last-Modified", playlist.mtime); - - return true; } void @@ -191,15 +180,13 @@ db_selection_print(Response &r, Partition &partition, 0, std::numeric_limits::max()); } -static bool +static void PrintSongURIVisitor(Response &r, Partition &partition, const LightSong &song) { song_print_uri(r, partition, song); - - return true; } -static bool +static void PrintUniqueTag(Response &r, TagType tag_type, const Tag &tag) { @@ -211,8 +198,6 @@ PrintUniqueTag(Response &r, TagType tag_type, if (item.type != tag_type) r.Format("%s: %s\n", tag_item_names[item.type], item.value); - - return true; } void diff --git a/src/db/DatabaseQueue.cxx b/src/db/DatabaseQueue.cxx index 2c4fffa4d..1b9adcfdc 100644 --- a/src/db/DatabaseQueue.cxx +++ b/src/db/DatabaseQueue.cxx @@ -27,14 +27,13 @@ #include -static bool +static void AddToQueue(Partition &partition, const LightSong &song) { const Storage &storage = *partition.instance.storage; partition.playlist.AppendSong(partition.pc, DatabaseDetachSong(storage, song)); - return true; } void diff --git a/src/db/Helpers.cxx b/src/db/Helpers.cxx index 5ed6d43d3..bff14a3bb 100644 --- a/src/db/Helpers.cxx +++ b/src/db/Helpers.cxx @@ -67,15 +67,13 @@ StatsVisitTag(DatabaseStats &stats, StringSet &artists, StringSet &albums, } } -static bool +static void StatsVisitSong(DatabaseStats &stats, StringSet &artists, StringSet &albums, const LightSong &song) { ++stats.song_count; StatsVisitTag(stats, artists, albums, *song.tag); - - return true; } DatabaseStats From 38d263ac19013d6f5debbf2e6d0d74efd901977c Mon Sep 17 00:00:00 2001 From: Max Kellermann Date: Wed, 1 Feb 2017 19:53:23 +0100 Subject: [PATCH 6/9] output/sndio: work around a libroar C++ incompatibility Same as in commit e02d8ad8d29ac, but this time for the sndio plugin which can be emulated by libroar. --- NEWS | 2 ++ src/output/plugins/SndioOutputPlugin.cxx | 8 ++++++++ 2 files changed, 10 insertions(+) diff --git a/NEWS b/NEWS index fb9111ead..01c190ac9 100644 --- a/NEWS +++ b/NEWS @@ -1,4 +1,6 @@ ver 0.20.4 (not yet released) +* output + - sndio: work around a libroar C++ incompatibility * workaround for GCC 4.9 "constexpr" bug * fix FreeBSD build failure diff --git a/src/output/plugins/SndioOutputPlugin.cxx b/src/output/plugins/SndioOutputPlugin.cxx index c5f63dfd7..b0050d6ae 100644 --- a/src/output/plugins/SndioOutputPlugin.cxx +++ b/src/output/plugins/SndioOutputPlugin.cxx @@ -24,8 +24,16 @@ #include "util/Domain.hxx" #include "Log.hxx" +/* work around a C++ incompatibility if the sndio API is emulated by + libroar: libroar's "struct roar_service_stream" has a member named + "new", which is an illegal identifier in C++ */ +#define new new_ + #include +/* undo the libroar workaround */ +#undef new + #include #ifndef SIO_DEVANY From 05eac20ffe5af325ac7d4019e72d3ac0b69d494a Mon Sep 17 00:00:00 2001 From: Max Kellermann Date: Wed, 1 Feb 2017 21:16:50 +0100 Subject: [PATCH 7/9] lib/nfs/Connection: detect libnfs reconnect When rpc_reconnect_requeue() gets called from inside nfs_service(), the NfsInputStream can stall completely because the old socket has been unregistered from epoll automatically, but the new one has never been registered. Therefore, nfs_service() will never be called again. This kludge attempts to detect this condition by checking nfs_which_events()==POLLOUT. https://bugs.musicpd.org/view.php?id=4081 --- NEWS | 2 ++ src/lib/nfs/Connection.cxx | 13 ++++++++++++- 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/NEWS b/NEWS index 01c190ac9..d32a375c5 100644 --- a/NEWS +++ b/NEWS @@ -1,4 +1,6 @@ ver 0.20.4 (not yet released) +* input + - nfs: fix freeze after reconnect * output - sndio: work around a libroar C++ incompatibility * workaround for GCC 4.9 "constexpr" bug diff --git a/src/lib/nfs/Connection.cxx b/src/lib/nfs/Connection.cxx index 16f6c001d..e41c4acd8 100644 --- a/src/lib/nfs/Connection.cxx +++ b/src/lib/nfs/Connection.cxx @@ -396,6 +396,17 @@ NfsConnection::ScheduleSocket() assert(GetEventLoop().IsInside()); assert(context != nullptr); + const int which_events = nfs_which_events(context); + + if (which_events == POLLOUT && SocketMonitor::IsDefined()) + /* kludge: if libnfs asks only for POLLOUT, it means + that it is currently waiting for the connect() to + finish - rpc_reconnect_requeue() may have been + called from inside nfs_service(); we must now + unregister the old socket and register the new one + instead */ + SocketMonitor::Steal(); + if (!SocketMonitor::IsDefined()) { int _fd = nfs_get_fd(context); if (_fd < 0) @@ -405,7 +416,7 @@ NfsConnection::ScheduleSocket() SocketMonitor::Open(_fd); } - SocketMonitor::Schedule(libnfs_to_events(nfs_which_events(context))); + SocketMonitor::Schedule(libnfs_to_events(which_events)); } inline int From 591afa06474b7d71ddb1bf0b95e99387b3378c4c Mon Sep 17 00:00:00 2001 From: Max Kellermann Date: Wed, 1 Feb 2017 21:36:32 +0100 Subject: [PATCH 8/9] lib/nfs/Connection: detect socket hangup and unregister from epoll Fixes race condition when epoll_ctl() gets called after the socket has been closed, which may affect a different socket created by another thread meanwhile. --- src/lib/nfs/Connection.cxx | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/lib/nfs/Connection.cxx b/src/lib/nfs/Connection.cxx index e41c4acd8..b417f2fab 100644 --- a/src/lib/nfs/Connection.cxx +++ b/src/lib/nfs/Connection.cxx @@ -416,7 +416,8 @@ NfsConnection::ScheduleSocket() SocketMonitor::Open(_fd); } - SocketMonitor::Schedule(libnfs_to_events(which_events)); + SocketMonitor::Schedule(libnfs_to_events(which_events) + | SocketMonitor::HANGUP); } inline int @@ -453,10 +454,14 @@ NfsConnection::OnSocketReady(unsigned flags) bool closed = false; const bool was_mounted = mount_finished; - if (!mount_finished) + if (!mount_finished || (flags & SocketMonitor::HANGUP) != 0) /* until the mount is finished, the NFS client may use various sockets, therefore we unregister and re-register it each time */ + /* also re-register the socket if we got a HANGUP, + which is a sure sign that libnfs will close the + socket, which can lead to a race condition if + epoll_ctl() is called later */ SocketMonitor::Steal(); const int result = Service(flags); From 0a033fb10aeca8bf6e6bfc9a2f9d9e793ee61ac9 Mon Sep 17 00:00:00 2001 From: Max Kellermann Date: Wed, 1 Feb 2017 21:59:36 +0100 Subject: [PATCH 9/9] release v0.20.4 --- NEWS | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/NEWS b/NEWS index d32a375c5..edc8a8c4e 100644 --- a/NEWS +++ b/NEWS @@ -1,4 +1,4 @@ -ver 0.20.4 (not yet released) +ver 0.20.4 (2017/02/01) * input - nfs: fix freeze after reconnect * output