From a62d54425cb263baf4286408dca73800bb7b9fdf Mon Sep 17 00:00:00 2001 From: Max Kellermann Date: Wed, 30 Oct 2013 19:50:22 +0100 Subject: db/proxy: auto-reconnect --- src/db/ProxyDatabasePlugin.cxx | 78 ++++++++++++++++++++++++++++++++++-------- 1 file changed, 64 insertions(+), 14 deletions(-) (limited to 'src/db') diff --git a/src/db/ProxyDatabasePlugin.cxx b/src/db/ProxyDatabasePlugin.cxx index 4c8498d69..40b710e7f 100644 --- a/src/db/ProxyDatabasePlugin.cxx +++ b/src/db/ProxyDatabasePlugin.cxx @@ -73,8 +73,12 @@ public: DatabaseStats &stats, Error &error) const override; -protected: +private: bool Configure(const config_param ¶m, Error &error); + + bool Connect(Error &error); + bool CheckConnection(Error &error); + bool EnsureConnected(Error &error); }; static constexpr Domain libmpdclient_domain("libmpdclient"); @@ -231,30 +235,65 @@ ProxyDatabase::Configure(const config_param ¶m, gcc_unused Error &error) bool ProxyDatabase::Open(Error &error) { - connection = mpd_connection_new(host.empty() ? nullptr : host.c_str(), - port, 0); + if (!Connect(error)) + return false; + + root = Directory::NewRoot(); + + return true; +} + +void +ProxyDatabase::Close() +{ + root->Free(); + + if (connection != nullptr) + mpd_connection_free(connection); +} + +bool +ProxyDatabase::Connect(Error &error) +{ + const char *_host = host.empty() ? nullptr : host.c_str(); + connection = mpd_connection_new(_host, port, 0); if (connection == nullptr) { - error.Set(libmpdclient_domain, (int)MPD_ERROR_OOM, "Out of memory"); + error.Set(libmpdclient_domain, (int)MPD_ERROR_OOM, + "Out of memory"); return false; } if (!CheckError(connection, error)) { - mpd_connection_free(connection); + if (connection != nullptr) { + mpd_connection_free(connection); + connection = nullptr; + } + return false; } - root = Directory::NewRoot(); - return true; } -void -ProxyDatabase::Close() +bool +ProxyDatabase::CheckConnection(Error &error) { assert(connection != nullptr); - root->Free(); - mpd_connection_free(connection); + if (!mpd_connection_clear_error(connection)) { + mpd_connection_free(connection); + return Connect(error); + } + + return true; +} + +bool +ProxyDatabase::EnsureConnected(Error &error) +{ + return connection != nullptr + ? CheckConnection(error) + : Connect(error); } static Song * @@ -263,8 +302,9 @@ Convert(const struct mpd_song *song); Song * ProxyDatabase::GetSong(const char *uri, Error &error) const { - // TODO: implement - // TODO: auto-reconnect + // TODO: eliminate the const_cast + if (!const_cast(this)->EnsureConnected(error)) + return nullptr; if (!mpd_send_list_meta(connection, uri)) { CheckError(connection, error); @@ -522,7 +562,9 @@ ProxyDatabase::Visit(const DatabaseSelection &selection, VisitPlaylist visit_playlist, Error &error) const { - // TODO: auto-reconnect + // TODO: eliminate the const_cast + if (!const_cast(this)->EnsureConnected(error)) + return nullptr; if (!visit_directory && !visit_playlist && selection.recursive) /* this optimized code path can only be used under @@ -542,6 +584,10 @@ ProxyDatabase::VisitUniqueTags(const DatabaseSelection &selection, VisitString visit_string, Error &error) const { + // TODO: eliminate the const_cast + if (!const_cast(this)->EnsureConnected(error)) + return nullptr; + enum mpd_tag_type tag_type2 = Convert(tag_type); if (tag_type2 == MPD_TAG_COUNT) { error.Set(libmpdclient_domain, "Unsupported tag"); @@ -578,6 +624,10 @@ ProxyDatabase::GetStats(const DatabaseSelection &selection, // TODO: match (void)selection; + // TODO: eliminate the const_cast + if (!const_cast(this)->EnsureConnected(error)) + return nullptr; + struct mpd_stats *stats2 = mpd_run_stats(connection); if (stats2 == nullptr) -- cgit v1.2.3