release v0.20.4

-----BEGIN PGP SIGNATURE-----
 
 iQJEBAABCAAuFiEEA5IzWngIOJSkMBxDI26KWMbbRRIFAliSTDkQHG1heEBtdXNp
 Y3BkLm9yZwAKCRAjbopYxttFEsIQD/4iNkylzLp8mID2aFT690MFzv4TRXi2XS7v
 r3Rlx3hpGyDdzeXZeFc5zxsc9Ei8OfLcdFC/Umj9LjQanXakOxwsdhagrW9cadNX
 YLxkyVcREXalmzUvoWeRnya1LjoTdYA8llvG2tAJosXVr0o/GHZi56aHcrYnW2a6
 XD8kEk5k9beuEcBLk1rdZCTGPbVLwCFvMcpZ7j5Hd4kDGQjjw2aoEaPWchJdhLQh
 p+GRSU+A8hyTo9zy+aNO3cKvq6zqVxDLlHnIqh8XPWQoLPyWuD7ETvwERKmdmiPZ
 bSo0MR7azTlhkWbNZxjPHgZuacJDlwKvXPg1ofjn8VVcaVe5ONeX+1WP0ozUYqyU
 fmhLxMHKuwZcKo6do/jNhAVp//VBWhSwJHPA8kjBTuZHHc0HvgyTxlAgvzlrSswe
 dxc8vnvzgJfUKz5k7mf3amVg6Cu1CmNi59CkyL0NL+8N0inyMfdeQuQEYgbPoI6X
 jIRwACfXpMX75VtiDaNpnFLBjL5emE6u2bDoU2c5ezgpthaWjb0PqSmoLBBF8TNm
 k0ecXlIwCjT3pDcqmFdqgG3AJiYLTgX0rETC8PInl6toLzr2oVMVlijU3YK5PjMl
 nTvgs8TwprTWImgcBnidqRMb39p3AKs12pHfZ4Y5Iu82Bm60acZQMkv6sQh43Wyc
 +W2+T3D2IA==
 =b2Fz
 -----END PGP SIGNATURE-----

Merge tag 'v0.20.4'

release v0.20.4
This commit is contained in:
Max Kellermann 2017-02-01 22:05:33 +01:00
commit df4af2b550
11 changed files with 58 additions and 42 deletions

8
NEWS
View File

@ -1,5 +1,13 @@
ver 0.21 (not yet released)
ver 0.20.4 (2017/02/01)
* input
- nfs: fix freeze after reconnect
* output
- sndio: work around a libroar C++ incompatibility
* workaround for GCC 4.9 "constexpr" bug
* fix FreeBSD build failure
ver 0.20.3 (2017/01/25)
* protocol
- "playlistadd" creates new playlist if it does not exist, as documented

View File

@ -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'],
)

View File

@ -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

View File

@ -27,13 +27,12 @@
#include <functional>
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

View File

@ -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<int>::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

View File

@ -27,14 +27,13 @@
#include <functional>
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

View File

@ -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

View File

@ -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,8 @@ NfsConnection::ScheduleSocket()
SocketMonitor::Open(_fd);
}
SocketMonitor::Schedule(libnfs_to_events(nfs_which_events(context)));
SocketMonitor::Schedule(libnfs_to_events(which_events)
| SocketMonitor::HANGUP);
}
inline int
@ -442,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);

View File

@ -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 <sndio.h>
/* undo the libroar workaround */
#undef new
#include <stdexcept>
#ifndef SIO_DEVANY

View File

@ -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) {

View File

@ -36,6 +36,7 @@
#include <type_traits>
#include <utility>
#include <new>
#include <cstdlib>
/**
* Allocate and construct a variable-size object. That is useful for