Skip to content

Commit

Permalink
Merge tag 'v0.21.23'
Browse files Browse the repository at this point in the history
release v0.21.23
  • Loading branch information
MaxKellermann committed Apr 23, 2020
2 parents 6979be0 + 6c240f6 commit 0b3acc3
Show file tree
Hide file tree
Showing 20 changed files with 238 additions and 60 deletions.
18 changes: 18 additions & 0 deletions NEWS
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,24 @@ ver 0.22 (not yet released)
* switch to C++17
- GCC 7 or clang 4 (or newer) recommended

ver 0.21.23 (2020/04/23)
* protocol
- add tag fallback for AlbumSort
* storage
- curl: fix corrupt "href" values in the presence of XML entities
- curl: unescape "href" values
* input
- nfs: fix crash bug
- nfs: fix freeze bug on reconnect
* decoder
- gme: adapt to API change in the upcoming version 0.7.0
* output
- alsa: implement channel mapping for 5.0 and 7.0
* player
- drain outputs at end of song in "single" mode
* Windows
- fix case insensitive search

ver 0.21.22 (2020/04/02)
* database
- simple: optimize startup
Expand Down
4 changes: 2 additions & 2 deletions android/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="org.musicpd"
android:installLocation="auto"
android:versionCode="45"
android:versionName="0.21.22">
android:versionCode="46"
android:versionName="0.21.23">

<uses-sdk android:minSdkVersion="21" android:targetSdkVersion="28"/>

Expand Down
6 changes: 5 additions & 1 deletion src/decoder/plugins/GmeDecoderPlugin.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -187,7 +187,11 @@ gme_file_decode(DecoderClient &client, Path path_fs)
LogWarning(gme_domain, gme_err);

if (length > 0)
gme_set_fade(emu, length);
gme_set_fade(emu, length
#if GME_VERSION >= 0x000700
, 8000
#endif
);

/* play */
DecoderCommand cmd;
Expand Down
4 changes: 2 additions & 2 deletions src/event/PollGroupWinSelect.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,8 @@

#include "PollGroupWinSelect.hxx"

constexpr int EVENT_READ = 0;
constexpr int EVENT_WRITE = 1;
static constexpr int EVENT_READ = 0;
static constexpr int EVENT_WRITE = 1;

static constexpr
bool HasEvent(unsigned events, int event_id) noexcept
Expand Down
19 changes: 19 additions & 0 deletions src/event/SocketMonitor.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,10 @@
#include <cassert>
#include <utility>

#ifdef USE_EPOLL
#include <cerrno>
#endif

void
SocketMonitor::Dispatch(unsigned flags) noexcept
{
Expand Down Expand Up @@ -81,6 +85,21 @@ SocketMonitor::Schedule(unsigned flags) noexcept

if (success)
scheduled_flags = flags;
#ifdef USE_EPOLL
else if (errno == EBADF || errno == ENOENT)
/* the socket was probably closed by somebody else
(EBADF) or a new file descriptor with the same
number was created but not registered already
(ENOENT) - we can assume that there are no
scheduled events */
/* note that when this happens, we're actually lucky
that it has failed - imagine another thread may
meanwhile have created something on the same file
descriptor number, and has registered it; the
epoll_ctl() call above would then have succeeded,
but broke the other thread's epoll registration */
scheduled_flags = 0;
#endif

return success;
}
4 changes: 2 additions & 2 deletions src/event/SocketMonitor.hxx
Original file line number Diff line number Diff line change
Expand Up @@ -108,15 +108,15 @@ public:
}

bool ScheduleRead() noexcept {
return Schedule(GetScheduledFlags() | READ | HANGUP | ERROR);
return Schedule(GetScheduledFlags() | READ);
}

bool ScheduleWrite() noexcept {
return Schedule(GetScheduledFlags() | WRITE);
}

void CancelRead() noexcept {
Schedule(GetScheduledFlags() & ~(READ|HANGUP|ERROR));
Schedule(GetScheduledFlags() & ~READ);
}

void CancelWrite() noexcept {
Expand Down
5 changes: 5 additions & 0 deletions src/fs/NarrowPath.hxx
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,11 @@ public:
constexpr
#endif
operator Path() const noexcept {
#ifdef _UNICODE
if (value.IsNull())
return nullptr;
#endif

return value;
}
};
Expand Down
27 changes: 0 additions & 27 deletions src/lib/icu/CaseFold.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -34,12 +34,6 @@
#include <algorithm>
#endif

#ifdef _WIN32
#include "Win32.hxx"
#include <windows.h>
#endif

#include <cassert>
#include <memory>

#include <string.h>
Expand All @@ -65,27 +59,6 @@ try {
folded.SetSize(folded_length);
return UCharToUTF8({folded.begin(), folded.size()});

#elif defined(_WIN32)
const auto u = MultiByteToWideChar(CP_UTF8, src);

const int size = LCMapStringEx(LOCALE_NAME_INVARIANT,
LCMAP_SORTKEY|LINGUISTIC_IGNORECASE,
u.c_str(), -1, nullptr, 0,
nullptr, nullptr, 0);
if (size <= 0)
return AllocatedString<>::Duplicate(src);

std::unique_ptr<wchar_t[]> buffer(new wchar_t[size]);
int result = LCMapStringEx(LOCALE_NAME_INVARIANT,
LCMAP_SORTKEY|LINGUISTIC_IGNORECASE,
u.c_str(), -1, buffer.get(), size,
nullptr, nullptr, 0);
if (result <= 0)
return AllocatedString<>::Duplicate(src);

return WideCharToMultiByte(CP_UTF8,
{buffer.get(), size_t(result - 1)});

#else
#error not implemented
#endif
Expand Down
2 changes: 1 addition & 1 deletion src/lib/icu/CaseFold.hxx
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@

#include "config.h"

#if defined(HAVE_ICU) || defined(_WIN32)
#ifdef HAVE_ICU
#define HAVE_ICU_CASE_FOLD

#include <string_view>
Expand Down
2 changes: 1 addition & 1 deletion src/lib/icu/Collate.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ IcuCollate(std::string_view a, std::string_view b) noexcept
}

auto result = CompareStringEx(LOCALE_NAME_INVARIANT,
LINGUISTIC_IGNORECASE,
NORM_IGNORECASE,
wa.c_str(), -1,
wb.c_str(), -1,
nullptr, nullptr, 0);
Expand Down
50 changes: 50 additions & 0 deletions src/lib/icu/Compare.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,27 @@
#include "util/StringAPI.hxx"
#include "config.h"

#ifdef _WIN32
#include "Win32.hxx"
#include <windows.h>
#endif

#ifdef HAVE_ICU_CASE_FOLD

IcuCompare::IcuCompare(std::string_view _needle) noexcept
:needle(IcuCaseFold(_needle)) {}

#elif defined(_WIN32)

IcuCompare::IcuCompare(std::string_view _needle) noexcept
:needle(nullptr)
{
try {
needle = MultiByteToWideChar(CP_UTF8, _needle);
} catch (...) {
}
}

#else

IcuCompare::IcuCompare(std::string_view _needle) noexcept
Expand All @@ -39,6 +55,22 @@ IcuCompare::operator==(const char *haystack) const noexcept
{
#ifdef HAVE_ICU_CASE_FOLD
return StringIsEqual(IcuCaseFold(haystack).c_str(), needle.c_str());
#elif defined(_WIN32)
if (needle.IsNull())
/* the MultiByteToWideChar() call in the constructor
has failed, so let's always fail the comparison */
return false;

try {
auto w_haystack = MultiByteToWideChar(CP_UTF8, haystack);
return CompareStringEx(LOCALE_NAME_INVARIANT,
NORM_IGNORECASE,
w_haystack.c_str(), -1,
needle.c_str(), -1,
nullptr, nullptr, 0) == CSTR_EQUAL;
} catch (...) {
return false;
}
#else
return StringIsEqualIgnoreCase(haystack, needle.c_str());
#endif
Expand All @@ -50,6 +82,24 @@ IcuCompare::IsIn(const char *haystack) const noexcept
#ifdef HAVE_ICU_CASE_FOLD
return StringFind(IcuCaseFold(haystack).c_str(),
needle.c_str()) != nullptr;
#elif defined(_WIN32)
if (needle.IsNull())
/* the MultiByteToWideChar() call in the constructor
has failed, so let's always fail the comparison */
return false;

try {
auto w_haystack = MultiByteToWideChar(CP_UTF8, haystack);
return FindNLSStringEx(LOCALE_NAME_INVARIANT,
FIND_FROMSTART|NORM_IGNORECASE,
w_haystack.c_str(), -1,
needle.c_str(), -1,
nullptr,
nullptr, nullptr, 0) >= 0;
} catch (...) {
/* MultiByteToWideChar() has failed */
return false;
}
#elif defined(HAVE_STRCASESTR)
return strcasestr(haystack, needle.c_str()) != nullptr;
#else
Expand Down
14 changes: 12 additions & 2 deletions src/lib/icu/Compare.hxx
Original file line number Diff line number Diff line change
Expand Up @@ -25,13 +25,23 @@

#include <string_view>

#ifdef _WIN32
#include <wchar.h>
#endif

/**
* This class can compare one string ("needle") with lots of other
* strings ("haystacks") efficiently, ignoring case. With some
* configurations, it can prepare a case-folded version of the needle.
*/
class IcuCompare {
#ifdef _WIN32
/* Windows API functions work with wchar_t strings, so let's
cache the MultiByteToWideChar() result for performance */
AllocatedString<wchar_t> needle;
#else
AllocatedString<> needle;
#endif

public:
IcuCompare():needle(nullptr) {}
Expand All @@ -40,12 +50,12 @@ public:

IcuCompare(const IcuCompare &src) noexcept
:needle(src
? AllocatedString<>::Duplicate(src.needle)
? src.needle.Clone()
: nullptr) {}

IcuCompare &operator=(const IcuCompare &src) noexcept {
needle = src
? AllocatedString<>::Duplicate(src.needle)
? src.needle.Clone()
: nullptr;
return *this;
}
Expand Down
7 changes: 4 additions & 3 deletions src/lib/nfs/Connection.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -191,7 +191,9 @@ static constexpr int
events_to_libnfs(unsigned i) noexcept
{
return ((i & SocketMonitor::READ) ? POLLIN : 0) |
((i & SocketMonitor::WRITE) ? POLLOUT : 0);
((i & SocketMonitor::WRITE) ? POLLOUT : 0) |
((i & SocketMonitor::HANGUP) ? POLLHUP : 0) |
((i & SocketMonitor::ERROR) ? POLLERR : 0);
}

NfsConnection::~NfsConnection() noexcept
Expand Down Expand Up @@ -450,8 +452,7 @@ NfsConnection::ScheduleSocket() noexcept
SocketMonitor::Open(_fd);
}

SocketMonitor::Schedule(libnfs_to_events(which_events)
| SocketMonitor::HANGUP);
SocketMonitor::Schedule(libnfs_to_events(which_events));
}

inline int
Expand Down
20 changes: 12 additions & 8 deletions src/lib/nfs/FileReader.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -180,7 +180,6 @@ NfsFileReader::OnNfsConnectionDisconnected(std::exception_ptr e) noexcept
inline void
NfsFileReader::OpenCallback(nfsfh *_fh) noexcept
{
assert(state == State::OPEN);
assert(connection != nullptr);
assert(_fh != nullptr);

Expand All @@ -197,27 +196,33 @@ NfsFileReader::OpenCallback(nfsfh *_fh) noexcept
}

inline void
NfsFileReader::StatCallback(const struct stat *st) noexcept
NfsFileReader::StatCallback(const struct stat *_st) noexcept
{
assert(state == State::STAT);
assert(connection != nullptr);
assert(fh != nullptr);
assert(st != nullptr);
assert(_st != nullptr);

#if defined(_WIN32) && !defined(_WIN64)
/* on 32-bit Windows, libnfs enables -D_FILE_OFFSET_BITS=64,
but MPD (Meson) doesn't - to work around this mismatch, we
cast explicitly to "struct stat64" */
const auto *st = (const struct stat64 *)_st;
#else
const auto *st = _st;
#endif

if (!S_ISREG(st->st_mode)) {
OnNfsFileError(std::make_exception_ptr(std::runtime_error("Not a regular file")));
return;
}

state = State::IDLE;

OnNfsFileOpen(st->st_size);
}

void
NfsFileReader::OnNfsCallback(unsigned status, void *data) noexcept
{
switch (state) {
switch (std::exchange(state, State::IDLE)) {
case State::INITIAL:
case State::DEFER:
case State::MOUNT:
Expand All @@ -234,7 +239,6 @@ NfsFileReader::OnNfsCallback(unsigned status, void *data) noexcept
break;

case State::READ:
state = State::IDLE;
OnNfsFileRead(data, status);
break;
}
Expand Down
Loading

0 comments on commit 0b3acc3

Please sign in to comment.