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:
commit
df4af2b550
8
NEWS
8
NEWS
@ -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
|
||||
|
@ -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'],
|
||||
)
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
@ -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) {
|
||||
|
@ -36,6 +36,7 @@
|
||||
#include <type_traits>
|
||||
#include <utility>
|
||||
#include <new>
|
||||
#include <cstdlib>
|
||||
|
||||
/**
|
||||
* Allocate and construct a variable-size object. That is useful for
|
||||
|
Loading…
Reference in New Issue
Block a user