Commit 8e8fbe14 authored by Max Kellermann's avatar Max Kellermann

output/snapcast: implement Drain()

parent a8a39b6a
......@@ -76,6 +76,10 @@ SnapcastClient::LockPopQueue() noexcept
auto chunk = std::move(chunks.front());
chunks.pop();
if (chunks.empty())
output.drain_cond.notify_one();
return chunk;
}
......
......@@ -68,6 +68,13 @@ public:
/**
* Caller must lock the mutex.
*/
bool IsDrained() const noexcept {
return chunks.empty();
}
/**
* Caller must lock the mutex.
*/
void Cancel() noexcept {
ClearQueue(chunks);
}
......
......@@ -24,6 +24,7 @@
#include "output/Interface.hxx"
#include "output/Timer.hxx"
#include "thread/Mutex.hxx"
#include "thread/Cond.hxx"
#include "event/ServerSocket.hxx"
#include "event/InjectEvent.hxx"
#include "util/AllocatedArray.hxx"
......@@ -82,6 +83,12 @@ public:
*/
mutable Mutex mutex;
/**
* This cond is signalled when a #SnapcastClient has an empty
* queue.
*/
Cond drain_cond;
SnapcastOutput(EventLoop &_loop, const ConfigBlock &block);
~SnapcastOutput() noexcept override;
......@@ -162,13 +169,19 @@ public:
size_t Play(const void *chunk, size_t size) override;
// TODO: void Drain() override;
void Drain() override;
void Cancel() noexcept override;
bool Pause() override;
private:
void OnInject() noexcept;
/**
* Caller must lock the mutex.
*/
[[gnu::pure]]
bool IsDrained() const noexcept;
/* virtual methods from class ServerSocket */
void OnAccept(UniqueSocketDescriptor fd,
SocketAddress address, int uid) noexcept override;
......
......@@ -181,6 +181,9 @@ SnapcastOutput::RemoveClient(SnapcastClient &client) noexcept
client.unlink();
delete &client;
if (clients.empty())
drain_cond.notify_one();
}
std::chrono::steady_clock::duration
......@@ -261,6 +264,26 @@ SnapcastOutput::Pause()
return true;
}
inline bool
SnapcastOutput::IsDrained() const noexcept
{
if (!chunks.empty())
return false;
for (const auto &client : clients)
if (!client.IsDrained())
return false;
return true;
}
void
SnapcastOutput::Drain()
{
std::unique_lock<Mutex> protect(mutex);
drain_cond.wait(protect, [this]{ return IsDrained(); });
}
void
SnapcastOutput::Cancel() noexcept
{
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment