summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMax Kellermann <max@duempel.org>2014-03-02 00:17:32 +0100
committerMax Kellermann <max@duempel.org>2014-03-02 00:17:32 +0100
commit2bf2f34b1211bfde95ef4ada77147a8b65830084 (patch)
treea6e639ccd3d07d445968f888e59bab580981ce89
parent7453c26ec4838760dec767b2f99afff9eb537d53 (diff)
InputPlugin: allow init() to soft-fail
Add enum InputResult which is a tri-state. Input plugins may now fail and just become unavailable.
-rw-r--r--src/input/Init.cxx22
-rw-r--r--src/input/InputPlugin.hxx31
-rw-r--r--src/input/plugins/CdioParanoiaInputPlugin.cxx6
-rw-r--r--src/input/plugins/CurlInputPlugin.cxx10
-rw-r--r--src/input/plugins/FfmpegInputPlugin.cxx6
-rw-r--r--src/input/plugins/SmbclientInputPlugin.cxx6
6 files changed, 65 insertions, 16 deletions
diff --git a/src/input/Init.cxx b/src/input/Init.cxx
index 4b8eac320..5e64dcaed 100644
--- a/src/input/Init.cxx
+++ b/src/input/Init.cxx
@@ -25,6 +25,7 @@
#include "config/ConfigGlobal.hxx"
#include "config/ConfigOption.hxx"
#include "config/ConfigData.hxx"
+#include "Log.hxx"
#include <assert.h>
#include <string.h>
@@ -49,12 +50,29 @@ input_stream_global_init(Error &error)
/* the plugin is disabled in mpd.conf */
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;
- else {
+ break;
+
+ case InputPlugin::InitResult::ERROR:
error.FormatPrefix("Failed to initialize input plugin '%s': ",
plugin->name);
return false;
+
+ case InputPlugin::InitResult::UNAVAILABLE:
+ if (error.IsDefined()) {
+ FormatError(error,
+ "Input plugin '%s' is unavailable: ",
+ plugin->name);
+ error.Clear();
+ }
+
+ break;
}
}
diff --git a/src/input/InputPlugin.hxx b/src/input/InputPlugin.hxx
index 83e0ab26e..090c73df8 100644
--- a/src/input/InputPlugin.hxx
+++ b/src/input/InputPlugin.hxx
@@ -26,12 +26,41 @@
#include <stddef.h>
#include <stdint.h>
+#ifdef WIN32
+#include <windows.h>
+/* damn you, windows.h! */
+#ifdef ERROR
+#undef ERROR
+#endif
+#endif
+
struct config_param;
struct InputStream;
class Error;
struct Tag;
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;
const char *name;
@@ -42,7 +71,7 @@ struct InputPlugin {
* @return true on success, false if the plugin should be
* disabled
*/
- bool (*init)(const config_param &param, Error &error);
+ InitResult (*init)(const config_param &param, Error &error);
/**
* Global deinitialization. Called once before MPD shuts
diff --git a/src/input/plugins/CdioParanoiaInputPlugin.cxx b/src/input/plugins/CdioParanoiaInputPlugin.cxx
index 9267b50e1..767b2600f 100644
--- a/src/input/plugins/CdioParanoiaInputPlugin.cxx
+++ b/src/input/plugins/CdioParanoiaInputPlugin.cxx
@@ -87,7 +87,7 @@ static constexpr Domain cdio_domain("cdio");
static bool default_reverse_endian;
-static bool
+static InputPlugin::InitResult
input_cdio_init(const config_param &param, Error &error)
{
const char *value = param.GetBlockValue("default_byte_order");
@@ -100,11 +100,11 @@ input_cdio_init(const config_param &param, Error &error)
error.Format(config_domain, 0,
"Unrecognized 'default_byte_order' setting: %s",
value);
- return false;
+ return InputPlugin::InitResult::ERROR;
}
}
- return true;
+ return InputPlugin::InitResult::SUCCESS;
}
static void
diff --git a/src/input/plugins/CurlInputPlugin.cxx b/src/input/plugins/CurlInputPlugin.cxx
index 3704aa35a..3f496cb96 100644
--- a/src/input/plugins/CurlInputPlugin.cxx
+++ b/src/input/plugins/CurlInputPlugin.cxx
@@ -595,7 +595,7 @@ CurlMulti::OnTimeout()
*
*/
-static bool
+static InputPlugin::InitResult
input_curl_init(const config_param &param, Error &error)
{
CURLcode code = curl_global_init(CURL_GLOBAL_ALL);
@@ -603,7 +603,7 @@ input_curl_init(const config_param &param, Error &error)
error.Format(curl_domain, code,
"curl_global_init() failed: %s",
curl_easy_strerror(code));
- return false;
+ return InputPlugin::InitResult::UNAVAILABLE;
}
const auto version_info = curl_version_info(CURLVERSION_FIRST);
@@ -634,12 +634,14 @@ input_curl_init(const config_param &param, Error &error)
CURLM *multi = curl_multi_init();
if (multi == nullptr) {
+ curl_slist_free_all(http_200_aliases);
+ curl_global_cleanup();
error.Set(curl_domain, 0, "curl_multi_init() failed");
- return false;
+ return InputPlugin::InitResult::UNAVAILABLE;
}
curl_multi = new CurlMulti(io_thread_get(), multi);
- return true;
+ return InputPlugin::InitResult::SUCCESS;
}
static void
diff --git a/src/input/plugins/FfmpegInputPlugin.cxx b/src/input/plugins/FfmpegInputPlugin.cxx
index 0d0a4375e..dab4b59fb 100644
--- a/src/input/plugins/FfmpegInputPlugin.cxx
+++ b/src/input/plugins/FfmpegInputPlugin.cxx
@@ -69,7 +69,7 @@ input_ffmpeg_supported(void)
return avio_enum_protocols(&opaque, 0) != nullptr;
}
-static bool
+static InputPlugin::InitResult
input_ffmpeg_init(gcc_unused const config_param &param,
Error &error)
{
@@ -78,10 +78,10 @@ input_ffmpeg_init(gcc_unused const config_param &param,
/* disable this plugin if there's no registered protocol */
if (!input_ffmpeg_supported()) {
error.Set(ffmpeg_domain, "No protocol");
- return false;
+ return InputPlugin::InitResult::UNAVAILABLE;
}
- return true;
+ return InputPlugin::InitResult::SUCCESS;
}
static InputStream *
diff --git a/src/input/plugins/SmbclientInputPlugin.cxx b/src/input/plugins/SmbclientInputPlugin.cxx
index 6f2c191b0..9709d089a 100644
--- a/src/input/plugins/SmbclientInputPlugin.cxx
+++ b/src/input/plugins/SmbclientInputPlugin.cxx
@@ -91,17 +91,17 @@ public:
*
*/
-static bool
+static InputPlugin::InitResult
input_smbclient_init(gcc_unused const config_param &param, Error &error)
{
if (!SmbclientInit(error))
- return false;
+ return InputPlugin::InitResult::UNAVAILABLE;
// TODO: create one global SMBCCTX here?
// TODO: evaluate config_param, call smbc_setOption*()
- return true;
+ return InputPlugin::InitResult::SUCCESS;
}
static InputStream *