mirror of
https://github.com/badaix/snapcast.git
synced 2025-05-14 17:46:45 +02:00
Switch to exception_ptr for async exceptions
This commit is contained in:
parent
5e508cae2e
commit
d49b5c251c
5 changed files with 24 additions and 36 deletions
|
@ -211,13 +211,10 @@ void ClientConnection::reader()
|
||||||
getNextMessage();
|
getNextMessage();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (const std::exception& e)
|
|
||||||
{
|
|
||||||
if (messageReceiver_ != nullptr)
|
|
||||||
messageReceiver_->onException(this, make_shared<SnapException>(e.what()));
|
|
||||||
}
|
|
||||||
catch (...)
|
catch (...)
|
||||||
{
|
{
|
||||||
|
if (messageReceiver_ != nullptr)
|
||||||
|
messageReceiver_->onException(this, std::current_exception());
|
||||||
}
|
}
|
||||||
active_ = false;
|
active_ = false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -78,17 +78,13 @@ private:
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
/// would be nicer to use std::exception_ptr
|
|
||||||
/// but not supported on all plattforms
|
|
||||||
typedef std::shared_ptr<std::exception> shared_exception_ptr;
|
|
||||||
|
|
||||||
/// Interface: callback for a received message and error reporting
|
/// Interface: callback for a received message and error reporting
|
||||||
class MessageReceiver
|
class MessageReceiver
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
virtual ~MessageReceiver() = default;
|
virtual ~MessageReceiver() = default;
|
||||||
virtual void onMessageReceived(ClientConnection* connection, const msg::BaseMessage& baseMessage, char* buffer) = 0;
|
virtual void onMessageReceived(ClientConnection* connection, const msg::BaseMessage& baseMessage, char* buffer) = 0;
|
||||||
virtual void onException(ClientConnection* connection, shared_exception_ptr exception) = 0;
|
virtual void onException(ClientConnection* connection, std::exception_ptr exception) = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -46,9 +46,9 @@ Controller::Controller(const ClientSettings& settings, std::unique_ptr<MetadataA
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void Controller::onException(ClientConnection* /*connection*/, shared_exception_ptr exception)
|
void Controller::onException(ClientConnection* /*connection*/, std::exception_ptr exception)
|
||||||
{
|
{
|
||||||
LOG(ERROR) << "Controller::onException: " << exception->what() << "\n";
|
LOG(ERROR) << "Controller::onException\n";
|
||||||
async_exception_ = exception;
|
async_exception_ = exception;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -159,16 +159,16 @@ void Controller::onMessageReceived(ClientConnection* /*connection*/, const msg::
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (baseMessage.type != message_type::kTime)
|
// if (baseMessage.type != message_type::kTime)
|
||||||
if (sendTimeSyncMessage(1000))
|
// if (sendTimeSyncMessage(1000))
|
||||||
LOG(DEBUG) << "time sync onMessageReceived\n";
|
// LOG(DEBUG) << "time sync onMessageReceived\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool Controller::sendTimeSyncMessage(long after)
|
bool Controller::sendTimeSyncMessage(const std::chrono::milliseconds& after)
|
||||||
{
|
{
|
||||||
static long lastTimeSync(0);
|
static chronos::time_point_clk lastTimeSync(chronos::clk::now());
|
||||||
long now = chronos::getTickCount();
|
auto now = chronos::clk::now();
|
||||||
if (lastTimeSync + after > now)
|
if (lastTimeSync + after > now)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
@ -227,8 +227,8 @@ void Controller::worker()
|
||||||
{
|
{
|
||||||
if (async_exception_)
|
if (async_exception_)
|
||||||
{
|
{
|
||||||
LOG(DEBUG) << "Async exception: " << async_exception_->what() << "\n";
|
LOG(DEBUG) << "Async exception\n";
|
||||||
throw SnapException(async_exception_->what());
|
std::rethrow_exception(async_exception_);
|
||||||
}
|
}
|
||||||
|
|
||||||
auto reply = clientConnection_->sendReq<msg::Time>(&timeReq, chronos::msec(2000));
|
auto reply = clientConnection_->sendReq<msg::Time>(&timeReq, chronos::msec(2000));
|
||||||
|
@ -249,12 +249,12 @@ void Controller::worker()
|
||||||
chronos::sleep(100);
|
chronos::sleep(100);
|
||||||
if (async_exception_)
|
if (async_exception_)
|
||||||
{
|
{
|
||||||
LOG(DEBUG) << "Async exception: " << async_exception_->what() << "\n";
|
LOG(DEBUG) << "Async exception\n";
|
||||||
throw SnapException(async_exception_->what());
|
std::rethrow_exception(async_exception_);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sendTimeSyncMessage(5000))
|
if (sendTimeSyncMessage(1000ms))
|
||||||
LOG(DEBUG) << "time sync main loop\n";
|
LOG(DEBUG) << "time sync main loop\n";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -42,6 +42,7 @@
|
||||||
#include "metadata.hpp"
|
#include "metadata.hpp"
|
||||||
#include "stream.hpp"
|
#include "stream.hpp"
|
||||||
|
|
||||||
|
using namespace std::chrono_literals;
|
||||||
|
|
||||||
/// Forwards PCM data to the audio player
|
/// Forwards PCM data to the audio player
|
||||||
/**
|
/**
|
||||||
|
@ -64,11 +65,11 @@ public:
|
||||||
|
|
||||||
/// Implementation of MessageReceiver.
|
/// Implementation of MessageReceiver.
|
||||||
/// Used for async exception reporting
|
/// Used for async exception reporting
|
||||||
void onException(ClientConnection* connection, shared_exception_ptr exception) override;
|
void onException(ClientConnection* connection, std::exception_ptr exception) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void worker();
|
void worker();
|
||||||
bool sendTimeSyncMessage(long after = 1000);
|
bool sendTimeSyncMessage(const std::chrono::milliseconds& after = 1000ms);
|
||||||
ClientSettings settings_;
|
ClientSettings settings_;
|
||||||
std::string meta_callback_;
|
std::string meta_callback_;
|
||||||
std::atomic<bool> active_;
|
std::atomic<bool> active_;
|
||||||
|
@ -83,7 +84,7 @@ private:
|
||||||
std::unique_ptr<msg::CodecHeader> headerChunk_;
|
std::unique_ptr<msg::CodecHeader> headerChunk_;
|
||||||
std::mutex receiveMutex_;
|
std::mutex receiveMutex_;
|
||||||
|
|
||||||
shared_exception_ptr async_exception_;
|
std::exception_ptr async_exception_;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -117,16 +117,10 @@ void Stream::clearChunks()
|
||||||
|
|
||||||
void Stream::addChunk(unique_ptr<msg::PcmChunk> chunk)
|
void Stream::addChunk(unique_ptr<msg::PcmChunk> chunk)
|
||||||
{
|
{
|
||||||
// drop chunks that should have been played 10s before. Just in case, this shouldn't happen.
|
// drop chunk if it's too old. Just in case, this shouldn't happen.
|
||||||
while (!chunks_.empty())
|
cs::usec age = std::chrono::duration_cast<cs::usec>(TimeProvider::serverNow() - chunk->start());
|
||||||
{
|
if (age > 5s + bufferMs_)
|
||||||
auto first_chunk = chunks_.front();
|
return;
|
||||||
cs::usec age = std::chrono::duration_cast<cs::usec>(TimeProvider::serverNow() - first_chunk->start());
|
|
||||||
if (age > 10s + bufferMs_)
|
|
||||||
chunks_.pop();
|
|
||||||
else
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
// LOG(DEBUG, LOG_TAG) << "new chunk: " << chunk->durationMs() << " ms, Chunks: " << chunks_.size() << "\n";
|
// LOG(DEBUG, LOG_TAG) << "new chunk: " << chunk->durationMs() << " ms, Chunks: " << chunks_.size() << "\n";
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue