InputPlugin: allow init() to soft-fail
Add enum InputResult which is a tri-state. Input plugins may now fail and just become unavailable.
This commit is contained in:
parent
7453c26ec4
commit
2bf2f34b12
@ -25,6 +25,7 @@
|
|||||||
#include "config/ConfigGlobal.hxx"
|
#include "config/ConfigGlobal.hxx"
|
||||||
#include "config/ConfigOption.hxx"
|
#include "config/ConfigOption.hxx"
|
||||||
#include "config/ConfigData.hxx"
|
#include "config/ConfigData.hxx"
|
||||||
|
#include "Log.hxx"
|
||||||
|
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
@ -49,12 +50,29 @@ input_stream_global_init(Error &error)
|
|||||||
/* the plugin is disabled in mpd.conf */
|
/* the plugin is disabled in mpd.conf */
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (plugin->init == nullptr || plugin->init(*param, error))
|
InputPlugin::InitResult result = plugin->init != nullptr
|
||||||
|
? plugin->init(*param, error)
|
||||||
|
: InputPlugin::InitResult::SUCCESS;
|
||||||
|
|
||||||
|
switch (result) {
|
||||||
|
case InputPlugin::InitResult::SUCCESS:
|
||||||
input_plugins_enabled[i] = true;
|
input_plugins_enabled[i] = true;
|
||||||
else {
|
break;
|
||||||
|
|
||||||
|
case InputPlugin::InitResult::ERROR:
|
||||||
error.FormatPrefix("Failed to initialize input plugin '%s': ",
|
error.FormatPrefix("Failed to initialize input plugin '%s': ",
|
||||||
plugin->name);
|
plugin->name);
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
case InputPlugin::InitResult::UNAVAILABLE:
|
||||||
|
if (error.IsDefined()) {
|
||||||
|
FormatError(error,
|
||||||
|
"Input plugin '%s' is unavailable: ",
|
||||||
|
plugin->name);
|
||||||
|
error.Clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -26,12 +26,41 @@
|
|||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#ifdef WIN32
|
||||||
|
#include <windows.h>
|
||||||
|
/* damn you, windows.h! */
|
||||||
|
#ifdef ERROR
|
||||||
|
#undef ERROR
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
struct config_param;
|
struct config_param;
|
||||||
struct InputStream;
|
struct InputStream;
|
||||||
class Error;
|
class Error;
|
||||||
struct Tag;
|
struct Tag;
|
||||||
|
|
||||||
struct InputPlugin {
|
struct InputPlugin {
|
||||||
|
enum class InitResult {
|
||||||
|
/**
|
||||||
|
* A fatal error has occurred (e.g. misconfiguration).
|
||||||
|
* The #Error has been set.
|
||||||
|
*/
|
||||||
|
ERROR,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The plugin was initialized successfully and is
|
||||||
|
* ready to be used.
|
||||||
|
*/
|
||||||
|
SUCCESS,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The plugin is not available and shall be disabled.
|
||||||
|
* The #Error may be set describing the situation (to
|
||||||
|
* be logged).
|
||||||
|
*/
|
||||||
|
UNAVAILABLE,
|
||||||
|
};
|
||||||
|
|
||||||
typedef int64_t offset_type;
|
typedef int64_t offset_type;
|
||||||
|
|
||||||
const char *name;
|
const char *name;
|
||||||
@ -42,7 +71,7 @@ struct InputPlugin {
|
|||||||
* @return true on success, false if the plugin should be
|
* @return true on success, false if the plugin should be
|
||||||
* disabled
|
* disabled
|
||||||
*/
|
*/
|
||||||
bool (*init)(const config_param ¶m, Error &error);
|
InitResult (*init)(const config_param ¶m, Error &error);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Global deinitialization. Called once before MPD shuts
|
* Global deinitialization. Called once before MPD shuts
|
||||||
|
@ -87,7 +87,7 @@ static constexpr Domain cdio_domain("cdio");
|
|||||||
|
|
||||||
static bool default_reverse_endian;
|
static bool default_reverse_endian;
|
||||||
|
|
||||||
static bool
|
static InputPlugin::InitResult
|
||||||
input_cdio_init(const config_param ¶m, Error &error)
|
input_cdio_init(const config_param ¶m, Error &error)
|
||||||
{
|
{
|
||||||
const char *value = param.GetBlockValue("default_byte_order");
|
const char *value = param.GetBlockValue("default_byte_order");
|
||||||
@ -100,11 +100,11 @@ input_cdio_init(const config_param ¶m, Error &error)
|
|||||||
error.Format(config_domain, 0,
|
error.Format(config_domain, 0,
|
||||||
"Unrecognized 'default_byte_order' setting: %s",
|
"Unrecognized 'default_byte_order' setting: %s",
|
||||||
value);
|
value);
|
||||||
return false;
|
return InputPlugin::InitResult::ERROR;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return InputPlugin::InitResult::SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -595,7 +595,7 @@ CurlMulti::OnTimeout()
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static bool
|
static InputPlugin::InitResult
|
||||||
input_curl_init(const config_param ¶m, Error &error)
|
input_curl_init(const config_param ¶m, Error &error)
|
||||||
{
|
{
|
||||||
CURLcode code = curl_global_init(CURL_GLOBAL_ALL);
|
CURLcode code = curl_global_init(CURL_GLOBAL_ALL);
|
||||||
@ -603,7 +603,7 @@ input_curl_init(const config_param ¶m, Error &error)
|
|||||||
error.Format(curl_domain, code,
|
error.Format(curl_domain, code,
|
||||||
"curl_global_init() failed: %s",
|
"curl_global_init() failed: %s",
|
||||||
curl_easy_strerror(code));
|
curl_easy_strerror(code));
|
||||||
return false;
|
return InputPlugin::InitResult::UNAVAILABLE;
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto version_info = curl_version_info(CURLVERSION_FIRST);
|
const auto version_info = curl_version_info(CURLVERSION_FIRST);
|
||||||
@ -634,12 +634,14 @@ input_curl_init(const config_param ¶m, Error &error)
|
|||||||
|
|
||||||
CURLM *multi = curl_multi_init();
|
CURLM *multi = curl_multi_init();
|
||||||
if (multi == nullptr) {
|
if (multi == nullptr) {
|
||||||
|
curl_slist_free_all(http_200_aliases);
|
||||||
|
curl_global_cleanup();
|
||||||
error.Set(curl_domain, 0, "curl_multi_init() failed");
|
error.Set(curl_domain, 0, "curl_multi_init() failed");
|
||||||
return false;
|
return InputPlugin::InitResult::UNAVAILABLE;
|
||||||
}
|
}
|
||||||
|
|
||||||
curl_multi = new CurlMulti(io_thread_get(), multi);
|
curl_multi = new CurlMulti(io_thread_get(), multi);
|
||||||
return true;
|
return InputPlugin::InitResult::SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -69,7 +69,7 @@ input_ffmpeg_supported(void)
|
|||||||
return avio_enum_protocols(&opaque, 0) != nullptr;
|
return avio_enum_protocols(&opaque, 0) != nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool
|
static InputPlugin::InitResult
|
||||||
input_ffmpeg_init(gcc_unused const config_param ¶m,
|
input_ffmpeg_init(gcc_unused const config_param ¶m,
|
||||||
Error &error)
|
Error &error)
|
||||||
{
|
{
|
||||||
@ -78,10 +78,10 @@ input_ffmpeg_init(gcc_unused const config_param ¶m,
|
|||||||
/* disable this plugin if there's no registered protocol */
|
/* disable this plugin if there's no registered protocol */
|
||||||
if (!input_ffmpeg_supported()) {
|
if (!input_ffmpeg_supported()) {
|
||||||
error.Set(ffmpeg_domain, "No protocol");
|
error.Set(ffmpeg_domain, "No protocol");
|
||||||
return false;
|
return InputPlugin::InitResult::UNAVAILABLE;
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return InputPlugin::InitResult::SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
static InputStream *
|
static InputStream *
|
||||||
|
@ -91,17 +91,17 @@ public:
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static bool
|
static InputPlugin::InitResult
|
||||||
input_smbclient_init(gcc_unused const config_param ¶m, Error &error)
|
input_smbclient_init(gcc_unused const config_param ¶m, Error &error)
|
||||||
{
|
{
|
||||||
if (!SmbclientInit(error))
|
if (!SmbclientInit(error))
|
||||||
return false;
|
return InputPlugin::InitResult::UNAVAILABLE;
|
||||||
|
|
||||||
// TODO: create one global SMBCCTX here?
|
// TODO: create one global SMBCCTX here?
|
||||||
|
|
||||||
// TODO: evaluate config_param, call smbc_setOption*()
|
// TODO: evaluate config_param, call smbc_setOption*()
|
||||||
|
|
||||||
return true;
|
return InputPlugin::InitResult::SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
static InputStream *
|
static InputStream *
|
||||||
|
Loading…
Reference in New Issue
Block a user