diff --git a/Makefile.am b/Makefile.am index 950c3e356..c29845938 100644 --- a/Makefile.am +++ b/Makefile.am @@ -293,6 +293,7 @@ libodbus_a_SOURCES = \ src/lib/dbus/ScopeMatch.cxx src/lib/dbus/ScopeMatch.hxx \ src/lib/dbus/Types.hxx \ src/lib/dbus/Values.hxx \ + src/lib/dbus/Glue.cxx src/lib/dbus/Glue.hxx \ src/lib/dbus/Watch.cxx src/lib/dbus/Watch.hxx libodbus_a_CPPFLAGS = $(AM_CPPFLAGS) $(DBUS_CFLAGS) endif diff --git a/src/lib/dbus/Glue.cxx b/src/lib/dbus/Glue.cxx new file mode 100644 index 000000000..8e8d25893 --- /dev/null +++ b/src/lib/dbus/Glue.cxx @@ -0,0 +1,45 @@ +/* + * Copyright 2003-2018 The Music Player Daemon Project + * http://www.musicpd.org + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#include "config.h" +#include "Glue.hxx" + +namespace ODBus { + +void +Glue::Connect() +{ + watch.SetConnection(Connection::GetSystem()); + + dbus_connection_set_exit_on_disconnect(GetConnection(), false); +} + +void +Glue::Disconnect() +{ + watch.SetConnection(Connection()); +} + +void +Glue::OnDBusClosed() noexcept +{ + // TODO: reconnect +} + +} diff --git a/src/lib/dbus/Glue.hxx b/src/lib/dbus/Glue.hxx new file mode 100644 index 000000000..49f35b170 --- /dev/null +++ b/src/lib/dbus/Glue.hxx @@ -0,0 +1,63 @@ +/* + * Copyright 2003-2018 The Music Player Daemon Project + * http://www.musicpd.org + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#ifndef MPD_DBUS_GLUE_HXX +#define MPD_DBUS_GLUE_HXX + +#include "Watch.hxx" + +class EventLoop; + +namespace ODBus { + +/** + * A class which manages the D-Bus client connection. + */ +class Glue final : ODBus::WatchManagerObserver { + WatchManager watch; + +public: + explicit Glue(EventLoop &event_loop) + :watch(event_loop, *this) { + Connect(); + } + + ~Glue() noexcept { + Disconnect(); + } + + EventLoop &GetEventLoop() noexcept { + return watch.GetEventLoop(); + } + + Connection &GetConnection() noexcept { + return watch.GetConnection(); + } + +private: + void Connect(); + void Disconnect(); + + /* virtual methods from class ODBus::WatchManagerObserver */ + void OnDBusClosed() noexcept override; +}; + +} + +#endif diff --git a/src/neighbor/plugins/UdisksNeighborPlugin.cxx b/src/neighbor/plugins/UdisksNeighborPlugin.cxx index 602582545..c95ce0e65 100644 --- a/src/neighbor/plugins/UdisksNeighborPlugin.cxx +++ b/src/neighbor/plugins/UdisksNeighborPlugin.cxx @@ -21,7 +21,7 @@ #include "UdisksNeighborPlugin.hxx" #include "lib/dbus/Connection.hxx" #include "lib/dbus/Error.hxx" -#include "lib/dbus/Watch.hxx" +#include "lib/dbus/Glue.hxx" #include "lib/dbus/Message.hxx" #include "lib/dbus/PendingCall.hxx" #include "lib/dbus/ReadIter.hxx" @@ -34,6 +34,7 @@ #include "thread/Mutex.hxx" #include "util/Domain.hxx" #include "util/StringAPI.hxx" +#include "util/Manual.hxx" #include "Log.hxx" #include @@ -69,9 +70,11 @@ struct UdisksObject { }; class UdisksNeighborExplorer final - : public NeighborExplorer, ODBus::WatchManagerObserver { + : public NeighborExplorer { - ODBus::WatchManager dbus_watch; + EventLoop &event_loop; + + Manual dbus_glue; ODBus::PendingCall pending_list_call; @@ -85,13 +88,16 @@ class UdisksNeighborExplorer final std::map by_path; public: - UdisksNeighborExplorer(EventLoop &event_loop, + UdisksNeighborExplorer(EventLoop &_event_loop, NeighborListener &_listener) noexcept - :NeighborExplorer(_listener), - dbus_watch(event_loop, *this) {} + :NeighborExplorer(_listener), event_loop(_event_loop) {} auto &GetEventLoop() noexcept { - return dbus_watch.GetEventLoop(); + return event_loop; + } + + auto &&GetConnection() noexcept { + return dbus_glue->GetConnection(); } /* virtual methods from class NeighborExplorer */ @@ -99,10 +105,6 @@ public: void Close() noexcept override; List GetList() const noexcept override; -private: - /* virtual methods from class ODBus::WatchManagerObserver */ - void OnDBusClosed() noexcept override; - private: void Insert(UdisksObject &&o) noexcept; void Remove(const std::string &path) noexcept; @@ -127,10 +129,9 @@ UdisksNeighborExplorer::Open() { using namespace ODBus; - dbus_watch.SetConnection(Connection::GetSystem()); + dbus_glue.Construct(event_loop); - auto &connection = dbus_watch.GetConnection(); - dbus_connection_set_exit_on_disconnect(connection, false); + auto &connection = GetConnection(); try { Error error; @@ -152,7 +153,7 @@ UdisksNeighborExplorer::Open() pending_list_call = PendingCall::SendWithReply(connection, msg.Get()); pending_list_call.SetNotify(OnListNotify, this); } catch (...) { - dbus_watch.SetConnection(Connection()); + dbus_glue.Destruct(); throw; } } @@ -169,7 +170,7 @@ UdisksNeighborExplorer::Close() noexcept // TODO: remove_match // TODO: remove_filter - dbus_watch.SetConnection(Connection()); + dbus_glue.Destruct(); } template @@ -288,12 +289,6 @@ UdisksNeighborExplorer::GetList() const noexcept return result; } -void -UdisksNeighborExplorer::OnDBusClosed() noexcept -{ - // TODO: reconnect -} - void UdisksNeighborExplorer::Insert(UdisksObject &&o) noexcept {