Commit d52c7e7a authored by Max Kellermann's avatar Max Kellermann

output/httpd: throw C++ exception on init error

parent c4acccac
...@@ -150,9 +150,13 @@ private: ...@@ -150,9 +150,13 @@ private:
unsigned clients_max; unsigned clients_max;
public: public:
HttpdOutput(EventLoop &_loop); HttpdOutput(EventLoop &_loop, const ConfigBlock &block);
~HttpdOutput(); ~HttpdOutput();
operator AudioOutput *() {
return &base;
}
#if CLANG_OR_GCC_VERSION(4,7) #if CLANG_OR_GCC_VERSION(4,7)
constexpr constexpr
#endif #endif
...@@ -162,21 +166,6 @@ public: ...@@ -162,21 +166,6 @@ public:
using DeferredMonitor::GetEventLoop; using DeferredMonitor::GetEventLoop;
bool Init(const ConfigBlock &block, Error &error);
bool Configure(const ConfigBlock &block, Error &error);
AudioOutput *InitAndConfigure(const ConfigBlock &block,
Error &error) {
if (!Init(block, error))
return nullptr;
if (!Configure(block, error))
return nullptr;
return &base;
}
void Bind(); void Bind();
void Unbind(); void Unbind();
......
...@@ -32,6 +32,7 @@ ...@@ -32,6 +32,7 @@
#include "system/fd_util.h" #include "system/fd_util.h"
#include "IOThread.hxx" #include "IOThread.hxx"
#include "event/Call.hxx" #include "event/Call.hxx"
#include "util/RuntimeError.hxx"
#include "util/Error.hxx" #include "util/Error.hxx"
#include "util/Domain.hxx" #include "util/Domain.hxx"
#include "util/DeleteDisposer.hxx" #include "util/DeleteDisposer.hxx"
...@@ -50,45 +51,12 @@ ...@@ -50,45 +51,12 @@
const Domain httpd_output_domain("httpd_output"); const Domain httpd_output_domain("httpd_output");
inline inline
HttpdOutput::HttpdOutput(EventLoop &_loop) HttpdOutput::HttpdOutput(EventLoop &_loop, const ConfigBlock &block)
:ServerSocket(_loop), DeferredMonitor(_loop), :ServerSocket(_loop), DeferredMonitor(_loop),
base(httpd_output_plugin), base(httpd_output_plugin, block),
encoder(nullptr), unflushed_input(0), encoder(nullptr), unflushed_input(0),
metadata(nullptr) metadata(nullptr)
{ {
}
HttpdOutput::~HttpdOutput()
{
if (metadata != nullptr)
metadata->Unref();
delete prepared_encoder;
}
inline void
HttpdOutput::Bind()
{
open = false;
BlockingCall(GetEventLoop(), [this](){
ServerSocket::Open();
});
}
inline void
HttpdOutput::Unbind()
{
assert(!open);
BlockingCall(GetEventLoop(), [this](){
ServerSocket::Close();
});
}
inline bool
HttpdOutput::Configure(const ConfigBlock &block, Error &error)
{
/* read configuration */ /* read configuration */
name = block.GetBlockValue("name", "Set name in config"); name = block.GetBlockValue("name", "Set name in config");
genre = block.GetBlockValue("genre", "Set genre in config"); genre = block.GetBlockValue("genre", "Set genre in config");
...@@ -99,11 +67,8 @@ HttpdOutput::Configure(const ConfigBlock &block, Error &error) ...@@ -99,11 +67,8 @@ HttpdOutput::Configure(const ConfigBlock &block, Error &error)
const char *encoder_name = const char *encoder_name =
block.GetBlockValue("encoder", "vorbis"); block.GetBlockValue("encoder", "vorbis");
const auto encoder_plugin = encoder_plugin_get(encoder_name); const auto encoder_plugin = encoder_plugin_get(encoder_name);
if (encoder_plugin == nullptr) { if (encoder_plugin == nullptr)
error.Format(httpd_output_domain, throw FormatRuntimeError("No such encoder: %s", encoder_name);
"No such encoder: %s", encoder_name);
return false;
}
clients_max = block.GetBlockValue("max_clients", 0u); clients_max = block.GetBlockValue("max_clients", 0u);
...@@ -123,31 +88,40 @@ HttpdOutput::Configure(const ConfigBlock &block, Error &error) ...@@ -123,31 +88,40 @@ HttpdOutput::Configure(const ConfigBlock &block, Error &error)
content_type = prepared_encoder->GetMimeType(); content_type = prepared_encoder->GetMimeType();
if (content_type == nullptr) if (content_type == nullptr)
content_type = "application/octet-stream"; content_type = "application/octet-stream";
}
return true; HttpdOutput::~HttpdOutput()
{
if (metadata != nullptr)
metadata->Unref();
delete prepared_encoder;
} }
inline bool inline void
HttpdOutput::Init(const ConfigBlock &block, Error &error) HttpdOutput::Bind()
{ {
return base.Configure(block, error); open = false;
BlockingCall(GetEventLoop(), [this](){
ServerSocket::Open();
});
} }
static AudioOutput * inline void
httpd_output_init(const ConfigBlock &block, Error &error) HttpdOutput::Unbind()
{ {
HttpdOutput *httpd = new HttpdOutput(io_thread_get()); assert(!open);
try { BlockingCall(GetEventLoop(), [this](){
AudioOutput *result = httpd->InitAndConfigure(block, error); ServerSocket::Close();
if (result == nullptr) });
delete httpd; }
return result; static AudioOutput *
} catch (const std::runtime_error &e) { httpd_output_init(const ConfigBlock &block, Error &)
delete httpd; {
throw; return *new HttpdOutput(io_thread_get(), block);
}
} }
static void static void
......
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