Merge branch 'v0.21.x'
This commit is contained in:
7
NEWS
7
NEWS
@@ -8,6 +8,13 @@ ver 0.22 (not yet released)
|
|||||||
- ffmpeg: new plugin based on FFmpeg's libavfilter library
|
- ffmpeg: new plugin based on FFmpeg's libavfilter library
|
||||||
- hdcd: new plugin based on FFmpeg's "af_hdcd" for HDCD playback
|
- hdcd: new plugin based on FFmpeg's "af_hdcd" for HDCD playback
|
||||||
|
|
||||||
|
ver 0.21.8 (not yet released)
|
||||||
|
* output
|
||||||
|
- httpd: add missing mutex lock
|
||||||
|
- httpd: fix use-after-free bug
|
||||||
|
* fix Bonjour bug
|
||||||
|
* fix build failure with GCC 9
|
||||||
|
|
||||||
ver 0.21.7 (2019/04/03)
|
ver 0.21.7 (2019/04/03)
|
||||||
* input
|
* input
|
||||||
- qobuz/tidal: scan tags when loading a playlist
|
- qobuz/tidal: scan tags when loading a playlist
|
||||||
|
@@ -2,8 +2,8 @@
|
|||||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
package="org.musicpd"
|
package="org.musicpd"
|
||||||
android:installLocation="auto"
|
android:installLocation="auto"
|
||||||
android:versionCode="29"
|
android:versionCode="30"
|
||||||
android:versionName="0.21.7">
|
android:versionName="0.21.8">
|
||||||
|
|
||||||
<uses-sdk android:minSdkVersion="21" android:targetSdkVersion="26"/>
|
<uses-sdk android:minSdkVersion="21" android:targetSdkVersion="26"/>
|
||||||
|
|
||||||
|
@@ -568,7 +568,8 @@ ProxyDatabase::OnSocketReady(gcc_unused unsigned flags) noexcept
|
|||||||
if (!is_idle) {
|
if (!is_idle) {
|
||||||
// TODO: can this happen?
|
// TODO: can this happen?
|
||||||
IdleMonitor::Schedule();
|
IdleMonitor::Schedule();
|
||||||
return false;
|
SocketMonitor::Cancel();
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned idle = (unsigned)mpd_recv_idle(connection, false);
|
unsigned idle = (unsigned)mpd_recv_idle(connection, false);
|
||||||
@@ -586,7 +587,8 @@ ProxyDatabase::OnSocketReady(gcc_unused unsigned flags) noexcept
|
|||||||
idle_received |= idle;
|
idle_received |= idle;
|
||||||
is_idle = false;
|
is_idle = false;
|
||||||
IdleMonitor::Schedule();
|
IdleMonitor::Schedule();
|
||||||
return false;
|
SocketMonitor::Cancel();
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@@ -110,15 +110,9 @@ BufferedSocket::OnSocketReady(unsigned flags) noexcept
|
|||||||
if (flags & READ) {
|
if (flags & READ) {
|
||||||
assert(!input.IsFull());
|
assert(!input.IsFull());
|
||||||
|
|
||||||
if (!ReadToBuffer())
|
if (!ReadToBuffer() || !ResumeInput())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (!ResumeInput())
|
|
||||||
/* we must return "true" here or
|
|
||||||
SocketMonitor::Dispatch() will call
|
|
||||||
Cancel() on a freed object */
|
|
||||||
return true;
|
|
||||||
|
|
||||||
if (!input.IsFull())
|
if (!input.IsFull())
|
||||||
ScheduleRead();
|
ScheduleRead();
|
||||||
}
|
}
|
||||||
|
@@ -47,6 +47,11 @@ public:
|
|||||||
using SocketMonitor::Close;
|
using SocketMonitor::Close;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
/**
|
||||||
|
* @return the number of bytes read from the socket, 0 if the
|
||||||
|
* socket isn't ready for reading, -1 on error (the socket has
|
||||||
|
* been closed and probably destructed)
|
||||||
|
*/
|
||||||
ssize_t DirectRead(void *data, size_t length) noexcept;
|
ssize_t DirectRead(void *data, size_t length) noexcept;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@@ -46,6 +46,11 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
/**
|
||||||
|
* @return the number of bytes written to the socket, 0 if the
|
||||||
|
* socket isn't ready for writing, -1 on error (the socket has
|
||||||
|
* been closed and probably destructed)
|
||||||
|
*/
|
||||||
ssize_t DirectWrite(const void *data, size_t length) noexcept;
|
ssize_t DirectWrite(const void *data, size_t length) noexcept;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
@@ -33,8 +33,8 @@ SocketMonitor::Dispatch(unsigned flags) noexcept
|
|||||||
{
|
{
|
||||||
flags &= GetScheduledFlags();
|
flags &= GetScheduledFlags();
|
||||||
|
|
||||||
if (flags != 0 && !OnSocketReady(flags) && IsDefined())
|
if (flags != 0)
|
||||||
Cancel();
|
OnSocketReady(flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
SocketMonitor::~SocketMonitor() noexcept
|
SocketMonitor::~SocketMonitor() noexcept
|
||||||
|
@@ -168,7 +168,7 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
constexpr operator SocketAddress() const noexcept {
|
constexpr operator SocketAddress() const noexcept {
|
||||||
return SocketAddress((const struct sockaddr *)&address,
|
return SocketAddress((const struct sockaddr *)(const void *)&address,
|
||||||
sizeof(address));
|
sizeof(address));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -135,7 +135,7 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
constexpr operator SocketAddress() const noexcept {
|
constexpr operator SocketAddress() const noexcept {
|
||||||
return SocketAddress((const struct sockaddr *)&address,
|
return SocketAddress((const struct sockaddr *)(const void *)&address,
|
||||||
sizeof(address));
|
sizeof(address));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -154,7 +154,7 @@ HttpdClient::SendResponse() noexcept
|
|||||||
FormatWarning(httpd_output_domain,
|
FormatWarning(httpd_output_domain,
|
||||||
"failed to write to client: %s",
|
"failed to write to client: %s",
|
||||||
(const char *)msg);
|
(const char *)msg);
|
||||||
Close();
|
LockClose();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -428,6 +428,7 @@ void
|
|||||||
HttpdClient::OnSocketError(std::exception_ptr ep) noexcept
|
HttpdClient::OnSocketError(std::exception_ptr ep) noexcept
|
||||||
{
|
{
|
||||||
LogError(ep);
|
LogError(ep);
|
||||||
|
LockClose();
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@@ -142,6 +142,8 @@ public:
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Frees the client and removes it from the server's client list.
|
* Frees the client and removes it from the server's client list.
|
||||||
|
*
|
||||||
|
* Caller must lock the mutex.
|
||||||
*/
|
*/
|
||||||
void Close() noexcept;
|
void Close() noexcept;
|
||||||
|
|
||||||
|
@@ -208,10 +208,15 @@ public:
|
|||||||
return HasClients();
|
return HasClients();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Caller must lock the mutex.
|
||||||
|
*/
|
||||||
void AddClient(UniqueSocketDescriptor fd) noexcept;
|
void AddClient(UniqueSocketDescriptor fd) noexcept;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Removes a client from the httpd_output.clients linked list.
|
* Removes a client from the httpd_output.clients linked list.
|
||||||
|
*
|
||||||
|
* Caller must lock the mutex.
|
||||||
*/
|
*/
|
||||||
void RemoveClient(HttpdClient &client) noexcept;
|
void RemoveClient(HttpdClient &client) noexcept;
|
||||||
|
|
||||||
@@ -239,10 +244,14 @@ public:
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Broadcasts data from the encoder to all clients.
|
* Broadcasts data from the encoder to all clients.
|
||||||
|
*
|
||||||
|
* Mutext must not be locked.
|
||||||
*/
|
*/
|
||||||
void BroadcastFromEncoder();
|
void BroadcastFromEncoder();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* Mutext must not be locked.
|
||||||
|
*
|
||||||
* Throws #std::runtime_error on error.
|
* Throws #std::runtime_error on error.
|
||||||
*/
|
*/
|
||||||
void EncodeAndPlay(const void *chunk, size_t size);
|
void EncodeAndPlay(const void *chunk, size_t size);
|
||||||
@@ -251,6 +260,9 @@ public:
|
|||||||
|
|
||||||
size_t Play(const void *chunk, size_t size) override;
|
size_t Play(const void *chunk, size_t size) override;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Mutext must not be locked.
|
||||||
|
*/
|
||||||
void CancelAllClients() noexcept;
|
void CancelAllClients() noexcept;
|
||||||
|
|
||||||
void Cancel() noexcept override;
|
void Cancel() noexcept override;
|
||||||
|
@@ -50,7 +50,7 @@ protected:
|
|||||||
/* virtual methods from class SocketMonitor */
|
/* virtual methods from class SocketMonitor */
|
||||||
bool OnSocketReady(gcc_unused unsigned flags) noexcept override {
|
bool OnSocketReady(gcc_unused unsigned flags) noexcept override {
|
||||||
DNSServiceProcessResult(service_ref);
|
DNSServiceProcessResult(service_ref);
|
||||||
return false;
|
return true;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user