diff options
author | Philip Rauwolf <rauwolf@itestra.de> | 2013-04-18 15:35:57 +0200 |
---|---|---|
committer | Philip Rauwolf <rauwolf@itestra.de> | 2013-04-18 15:35:57 +0200 |
commit | 0e1b727ec4b141d88a44067a8994b08294aa4d40 (patch) | |
tree | 83214064743a0cef14380f81a8738286f85c01a3 | |
parent | 4c9bef27f9c9fdf4e9f06e4346da18264d6b9ac7 (diff) | |
download | genivi-common-api-dbus-runtime-0e1b727ec4b141d88a44067a8994b08294aa4d40.tar.gz |
Added and integrated necessary D-Bus Mainloop Context
Change-Id: Ia5c1f4585eabb919a75ec5fdc16c6ba8f053ab6b
-rw-r--r-- | Makefile.am | 170 | ||||
-rw-r--r-- | src/CommonAPI/DBus/DBusConnection.cpp | 191 | ||||
-rw-r--r-- | src/CommonAPI/DBus/DBusConnection.h | 178 | ||||
-rw-r--r-- | src/CommonAPI/DBus/DBusFactory.cpp | 17 | ||||
-rw-r--r-- | src/CommonAPI/DBus/DBusFactory.h | 6 | ||||
-rw-r--r-- | src/CommonAPI/DBus/DBusMainLoopContext.cpp | 143 | ||||
-rw-r--r-- | src/CommonAPI/DBus/DBusMainLoopContext.h | 94 | ||||
-rw-r--r-- | src/CommonAPI/DBus/DBusProxyConnection.h | 44 | ||||
-rw-r--r-- | src/CommonAPI/DBus/DBusRuntime.cpp | 4 | ||||
-rw-r--r-- | src/CommonAPI/DBus/DBusRuntime.h | 2 |
10 files changed, 639 insertions, 210 deletions
diff --git a/Makefile.am b/Makefile.am index 173c80a..e73fb5c 100644 --- a/Makefile.am +++ b/Makefile.am @@ -4,16 +4,16 @@ EXTRA_DIST = LICENSE LICENSE_dbus_patch LICENSE_MurmurHash MOSTLYCLEANFILES = AM_CPPFLAGS = \ - -include $(top_builddir)/build-aux/config.h \ - -I$(top_srcdir)/src \ - -I$(top_srcdir)/src/test \ - ${COMMONAPI_CFLAGS} \ - ${DBUS_CFLAGS} - + -include $(top_builddir)/build-aux/config.h \ + -I$(top_srcdir)/src \ + -I$(top_srcdir)/src/test \ + ${COMMONAPI_CFLAGS} \ + ${DBUS_CFLAGS} + AM_LDFLAGS = \ - ${COMMONAPI_LIBS} \ - ${DBUS_LIBS} + ${COMMONAPI_LIBS} \ + ${DBUS_LIBS} noinst_LTLIBRARIES = lib_LTLIBRARIES = @@ -27,41 +27,42 @@ LIBCOMMONAPI_DBUS_AGE=0 noinst_LTLIBRARIES += libmurmurhash-internal.la libmurmurhash_internal_la_SOURCES = \ - src/murmurhash/MurmurHash3.h \ - src/murmurhash/MurmurHash3.cpp + src/murmurhash/MurmurHash3.h \ + src/murmurhash/MurmurHash3.cpp # ------------------------------------------------------------------------------ lib_LTLIBRARIES += libCommonAPI-DBus.la libCommonAPI_DBus_la_SOURCES = \ - src/CommonAPI/DBus/DBusAddressTranslator.cpp \ - src/CommonAPI/DBus/DBusConnection.cpp \ - src/CommonAPI/DBus/DBusDaemonProxy.cpp \ - src/CommonAPI/DBus/DBusError.cpp \ - src/CommonAPI/DBus/DBusFunctionalHash.cpp \ - src/CommonAPI/DBus/DBusInputStream.cpp \ - src/CommonAPI/DBus/DBusMessage.cpp \ - src/CommonAPI/DBus/DBusObjectManager.cpp \ - src/CommonAPI/DBus/DBusOutputStream.cpp \ - src/CommonAPI/DBus/DBusProxyBase.cpp \ - src/CommonAPI/DBus/DBusProxy.cpp \ - src/CommonAPI/DBus/DBusFactory.cpp \ - src/CommonAPI/DBus/DBusRuntime.cpp \ - src/CommonAPI/DBus/DBusServiceRegistry.cpp \ - src/CommonAPI/DBus/DBusServiceStatusEvent.cpp \ - src/CommonAPI/DBus/DBusStubAdapter.cpp + src/CommonAPI/DBus/DBusAddressTranslator.cpp \ + src/CommonAPI/DBus/DBusConnection.cpp \ + src/CommonAPI/DBus/DBusDaemonProxy.cpp \ + src/CommonAPI/DBus/DBusError.cpp \ + src/CommonAPI/DBus/DBusFunctionalHash.cpp \ + src/CommonAPI/DBus/DBusInputStream.cpp \ + src/CommonAPI/DBus/DBusMainLoopContext.cpp \ + src/CommonAPI/DBus/DBusMessage.cpp \ + src/CommonAPI/DBus/DBusObjectManager.cpp \ + src/CommonAPI/DBus/DBusOutputStream.cpp \ + src/CommonAPI/DBus/DBusProxyBase.cpp \ + src/CommonAPI/DBus/DBusProxy.cpp \ + src/CommonAPI/DBus/DBusFactory.cpp \ + src/CommonAPI/DBus/DBusRuntime.cpp \ + src/CommonAPI/DBus/DBusServiceRegistry.cpp \ + src/CommonAPI/DBus/DBusServiceStatusEvent.cpp \ + src/CommonAPI/DBus/DBusStubAdapter.cpp libCommonAPI_DBus_la_LIBADD = \ - libmurmurhash-internal.la \ - ${COMMONAPI_LIBS} + libmurmurhash-internal.la \ + ${COMMONAPI_LIBS} libCommonAPI_DBus_la_LDFLAGS = \ - ${AM_LDFLAGS} \ - -version-info ${LIBCOMMONAPI_DBUS_CURRENT}:${LIBCOMMONAPI_DBUS_REVISION}:${LIBCOMMONAPI_DBUS_AGE} + ${AM_LDFLAGS} \ + -version-info ${LIBCOMMONAPI_DBUS_CURRENT}:${LIBCOMMONAPI_DBUS_REVISION}:${LIBCOMMONAPI_DBUS_AGE} CommonAPI_DBus_includedir=$(includedir)/CommonAPI-${VERSION}/CommonAPI/DBus CommonAPI_DBus_include_HEADERS = \ - src/CommonAPI/DBus/DBusAddressTranslator.h \ - src/CommonAPI/DBus/DBusAttribute.h \ + src/CommonAPI/DBus/DBusAddressTranslator.h \ + src/CommonAPI/DBus/DBusAttribute.h \ src/CommonAPI/DBus/DBusConnection.h \ src/CommonAPI/DBus/DBusDaemonProxy.h \ src/CommonAPI/DBus/DBusError.h \ @@ -69,6 +70,7 @@ CommonAPI_DBus_include_HEADERS = \ src/CommonAPI/DBus/DBusFunctionalHash.h \ src/CommonAPI/DBus/DBusHelper.h \ src/CommonAPI/DBus/DBusInputStream.h \ + src/CommonAPI/DBus/DBusMainLoopContext.h \ src/CommonAPI/DBus/DBusMessage.h \ src/CommonAPI/DBus/DBusMultiEvent.h \ src/CommonAPI/DBus/DBusObjectManager.h \ @@ -77,15 +79,15 @@ CommonAPI_DBus_include_HEADERS = \ src/CommonAPI/DBus/DBusProxy.h \ src/CommonAPI/DBus/DBusProxyAsyncCallbackHandler.h \ src/CommonAPI/DBus/DBusProxyConnection.h \ - src/CommonAPI/DBus/DBusFactory.h \ - src/CommonAPI/DBus/DBusProxyHelper.h \ - src/CommonAPI/DBus/DBusRuntime.h \ - src/CommonAPI/DBus/DBusSerializableArguments.h \ - src/CommonAPI/DBus/DBusServiceRegistry.h \ - src/CommonAPI/DBus/DBusServiceStatusEvent.h \ - src/CommonAPI/DBus/DBusStubAdapter.h \ - src/CommonAPI/DBus/DBusStubAdapterHelper.h \ - src/CommonAPI/DBus/DBusUtils.h + src/CommonAPI/DBus/DBusFactory.h \ + src/CommonAPI/DBus/DBusProxyHelper.h \ + src/CommonAPI/DBus/DBusRuntime.h \ + src/CommonAPI/DBus/DBusSerializableArguments.h \ + src/CommonAPI/DBus/DBusServiceRegistry.h \ + src/CommonAPI/DBus/DBusServiceStatusEvent.h \ + src/CommonAPI/DBus/DBusStubAdapter.h \ + src/CommonAPI/DBus/DBusStubAdapterHelper.h \ + src/CommonAPI/DBus/DBusUtils.h pkgconfigdir = ${libdir}/pkgconfig pkgconfig_DATA = CommonAPI-DBus.pc @@ -94,43 +96,43 @@ pkgconfig_DATA = CommonAPI-DBus.pc if ENABLE_TESTS TestInterfaceSources = \ - src/test/commonapi/tests/DerivedTypeCollection.cpp \ - src/test/commonapi/tests/TestInterfaceDBusProxy.cpp \ - src/test/commonapi/tests/TestInterfaceDBusStubAdapter.cpp \ - src/test/commonapi/tests/TestInterfaceStubDefault.cpp \ - src/test/fakeLegacyService/fake/legacy/service/LegacyInterfaceDBusProxy.cpp + src/test/commonapi/tests/DerivedTypeCollection.cpp \ + src/test/commonapi/tests/TestInterfaceDBusProxy.cpp \ + src/test/commonapi/tests/TestInterfaceDBusStubAdapter.cpp \ + src/test/commonapi/tests/TestInterfaceStubDefault.cpp \ + src/test/fakeLegacyService/fake/legacy/service/LegacyInterfaceDBusProxy.cpp check_PROGRAMS = \ - DBusConnectionTest \ - DBusServiceRegistryTest \ - DBusProxyTest \ - DBusAddressTranslatorTest \ - DBusInputStreamTest \ - DBusOutputStreamTest \ - DBusRuntimeTest \ - DBusFactoryTest \ - DBusVariantTest \ - DBusTypeStreamTest \ - DBusVariantOutputStreamTest \ - DBusDaemonProxyTest \ - DBusCommunicationTest \ - DBusMultipleConnectionTest \ - DBusBenchmarkingTest + DBusConnectionTest \ + DBusServiceRegistryTest \ + DBusProxyTest \ + DBusAddressTranslatorTest \ + DBusInputStreamTest \ + DBusOutputStreamTest \ + DBusRuntimeTest \ + DBusFactoryTest \ + DBusVariantTest \ + DBusTypeStreamTest \ + DBusVariantOutputStreamTest \ + DBusDaemonProxyTest \ + DBusCommunicationTest \ + DBusMultipleConnectionTest \ + DBusBenchmarkingTest TESTS = ${check_PROGRAMS} LDADD_FOR_GTEST = libCommonAPI-DBus.la ${GTEST_LIBS} ${LDADD} DBusServiceRegistryTest_SOURCES = \ - src/test/DBusServiceRegistryTest.cpp \ - ${TestInterfaceSources} + src/test/DBusServiceRegistryTest.cpp \ + ${TestInterfaceSources} DBusServiceRegistryTest_CPPFLAGS = ${AM_CPPFLAGS} ${GTEST_CPPFLAGS} DBusServiceRegistryTest_CXXFLAGS = ${GTEST_CXXFLAGS} DBusServiceRegistryTest_LDADD = ${LDADD_FOR_GTEST} DBusAddressTranslatorTest_SOURCES = \ - src/test/DBusAddressTranslatorTest.cpp \ - ${TestInterfaceSources} + src/test/DBusAddressTranslatorTest.cpp \ + ${TestInterfaceSources} DBusAddressTranslatorTest_CPPFLAGS = ${AM_CPPFLAGS} ${GTEST_CPPFLAGS} DBusAddressTranslatorTest_CXXFLAGS = ${GTEST_CXXFLAGS} DBusAddressTranslatorTest_LDADD = ${LDADD_FOR_GTEST} @@ -156,8 +158,8 @@ DBusBenchmarkingTest_CXXFLAGS = ${GTEST_CXXFLAGS} DBusBenchmarkingTest_LDADD = ${LDADD_FOR_GTEST} DBusCommunicationTest_SOURCES = \ - src/test/DBusCommunicationTest.cpp \ - ${TestInterfaceSources} + src/test/DBusCommunicationTest.cpp \ + ${TestInterfaceSources} DBusCommunicationTest_CPPFLAGS = ${AM_CPPFLAGS} ${GTEST_CPPFLAGS} DBusCommunicationTest_CXXFLAGS = ${GTEST_CXXFLAGS} DBusCommunicationTest_LDADD = ${LDADD_FOR_GTEST} @@ -168,22 +170,22 @@ DBusDaemonProxyTest_CXXFLAGS = ${GTEST_CXXFLAGS} DBusDaemonProxyTest_LDADD = ${LDADD_FOR_GTEST} DBusInputStreamTest_SOURCES = \ - src/test/DBusInputStreamTest.cpp \ - ${TestInterfaceSources} + src/test/DBusInputStreamTest.cpp \ + ${TestInterfaceSources} DBusInputStreamTest_CPPFLAGS = ${AM_CPPFLAGS} ${GTEST_CPPFLAGS} DBusInputStreamTest_CXXFLAGS = ${GTEST_CXXFLAGS} DBusInputStreamTest_LDADD = ${LDADD_FOR_GTEST} DBusOutputStreamTest_SOURCES = \ - src/test/DBusOutputStreamTest.cpp \ - ${TestInterfaceSources} + src/test/DBusOutputStreamTest.cpp \ + ${TestInterfaceSources} DBusOutputStreamTest_CPPFLAGS = ${AM_CPPFLAGS} ${GTEST_CPPFLAGS} DBusOutputStreamTest_CXXFLAGS = ${GTEST_CXXFLAGS} DBusOutputStreamTest_LDADD = ${LDADD_FOR_GTEST} DBusFactoryTest_SOURCES = \ - src/test/DBusFactoryTest.cpp \ - ${TestInterfaceSources} + src/test/DBusFactoryTest.cpp \ + ${TestInterfaceSources} DBusFactoryTest_CPPFLAGS = ${AM_CPPFLAGS} ${GTEST_CPPFLAGS} DBusFactoryTest_CXXFLAGS = ${GTEST_CXXFLAGS} DBusFactoryTest_LDADD = ${LDADD_FOR_GTEST} @@ -193,20 +195,16 @@ DBusRuntimeTest_CPPFLAGS = ${AM_CPPFLAGS} ${GTEST_CPPFLAGS} DBusRuntimeTest_CXXFLAGS = ${GTEST_CXXFLAGS} DBusRuntimeTest_LDADD = ${LDADD_FOR_GTEST} -#DBusStubAdapterTest_SOURCES = src/test/DBusStubAdapterTest.cpp -#DBusStubAdapterTest_CPPFLAGS = ${AM_CPPFLAGS} ${GTEST_CPPFLAGS} -#DBusStubAdapterTest_CXXFLAGS = ${GTEST_CXXFLAGS} -#DBusStubAdapterTest_LDADD = ${LDADD} ${GTEST_LIBS} libCommonAPI-DBus.la - -DBusMultipleConnectionTest_SOURCES = src/test/DBusMultipleConnectionTest.cpp \ - ${TestInterfaceSources} +DBusMultipleConnectionTest_SOURCES = \ + src/test/DBusMultipleConnectionTest.cpp \ + ${TestInterfaceSources} DBusMultipleConnectionTest_CPPFLAGS = ${AM_CPPFLAGS} ${GTEST_CPPFLAGS} DBusMultipleConnectionTest_CXXFLAGS = ${GTEST_CXXFLAGS} DBusMultipleConnectionTest_LDADD = ${LDADD_FOR_GTEST} DBusProxyTest_SOURCES = \ - src/test/DBusProxyTest.cpp \ - ${TestInterfaceSources} + src/test/DBusProxyTest.cpp \ + ${TestInterfaceSources} DBusProxyTest_CPPFLAGS = ${AM_CPPFLAGS} ${GTEST_CPPFLAGS} DBusProxyTest_CXXFLAGS = ${GTEST_CXXFLAGS} DBusProxyTest_LDADD = ${LDADD_FOR_GTEST} @@ -227,9 +225,9 @@ MOSTLYCLEANFILES += ${DX_CLEANFILES} # ------------------------------------------------------------------------------ MAINTAINERCLEANFILES = \ - Makefile.in \ - aclocal.m4 \ - configure + Makefile.in \ + aclocal.m4 \ + configure clean-local: -rm -rf src-gen @@ -238,4 +236,4 @@ maintainer-clean-local: -rm -rf build-aux -rm -f config.h.in* -rm -f m4/libtool*.m4 - -rm -f m4/lt*.m4
\ No newline at end of file + -rm -f m4/lt*.m4 diff --git a/src/CommonAPI/DBus/DBusConnection.cpp b/src/CommonAPI/DBus/DBusConnection.cpp index af259fd..df77e95 100644 --- a/src/CommonAPI/DBus/DBusConnection.cpp +++ b/src/CommonAPI/DBus/DBusConnection.cpp @@ -63,7 +63,9 @@ DBusConnection::DBusConnection(BusType busType) : dbusConnectionStatusEvent_(this), stopDispatching_(false), pauseDispatching_(false), - dbusObjectMessageHandler_() { + dispatchThread_(NULL), + dbusObjectMessageHandler_(), + watchContext_(NULL) { dbus_threads_init_default(); } @@ -73,7 +75,9 @@ DBusConnection::DBusConnection(::DBusConnection* libDbusConnection) : dbusConnectionStatusEvent_(this), stopDispatching_(false), pauseDispatching_(false), - dbusObjectMessageHandler_() { + dispatchThread_(NULL), + dbusObjectMessageHandler_(), + watchContext_(NULL) { dbus_threads_init_default(); } @@ -86,19 +90,159 @@ bool DBusConnection::isObjectPathMessageHandlerSet() { } DBusConnection::~DBusConnection() { + if(auto lockedContext = mainLoopContext_.lock()) { + dbus_connection_set_watch_functions(libdbusConnection_, NULL, NULL, NULL, NULL, NULL); + dbus_connection_set_timeout_functions(libdbusConnection_, NULL, NULL, NULL, NULL, NULL); + + lockedContext->deregisterDispatchSource(dispatchSource_); + delete watchContext_; + delete dispatchSource_; + } + disconnect(); } -bool DBusConnection::connect() { + +bool DBusConnection::attachMainLoopContext(std::weak_ptr<MainLoopContext> mainLoopContext) { + mainLoopContext_ = mainLoopContext; + + if (auto lockedContext = mainLoopContext_.lock()) { + dispatchSource_ = new DBusDispatchSource(this); + watchContext_ = new WatchContext(mainLoopContext_, dispatchSource_); + lockedContext->registerDispatchSource(dispatchSource_); + + dbus_connection_set_wakeup_main_function( + libdbusConnection_, + &DBusConnection::onWakeupMainContext, + &mainLoopContext_, + NULL); + + bool success = dbus_connection_set_watch_functions( + libdbusConnection_, + &DBusConnection::onAddWatch, + &DBusConnection::onRemoveWatch, + &DBusConnection::onToggleWatch, + watchContext_, + NULL); + + if (!success) { + return false; + } + + success = dbus_connection_set_timeout_functions( + libdbusConnection_, + &DBusConnection::onAddTimeout, + &DBusConnection::onRemoveTimeout, + &DBusConnection::onToggleTimeout, + &mainLoopContext_, + NULL); + + if (!success) { + dbus_connection_set_watch_functions(libdbusConnection_, NULL, NULL, NULL, NULL, NULL); + return false; + } + + return true; + } + return false; +} + +void DBusConnection::onWakeupMainContext(void* data) { + std::weak_ptr<MainLoopContext>* mainloop = static_cast<std::weak_ptr<MainLoopContext>*>(data); + assert(mainloop); + + if(auto lockedContext = mainloop->lock()) { + lockedContext->wakeup(); + } +} + + +dbus_bool_t DBusConnection::onAddWatch(::DBusWatch* libdbusWatch, void* data) { + WatchContext* watchContext = static_cast<WatchContext*>(data); + assert(watchContext); + + DBusWatch* dbusWatch = new DBusWatch(libdbusWatch, watchContext->mainLoopContext_); + dbusWatch->addDependentDispatchSource(watchContext->dispatchSource_); + dbus_watch_set_data(libdbusWatch, dbusWatch, NULL); + + if (dbusWatch->isReadyToBeWatched()) { + dbusWatch->startWatching(); + } + + return TRUE; +} + +void DBusConnection::onRemoveWatch(::DBusWatch* libdbusWatch, void* data) { + assert(static_cast<WatchContext*>(data)); + + DBusWatch* dbusWatch = static_cast<DBusWatch*>(dbus_watch_get_data(libdbusWatch)); + if(dbusWatch->isReadyToBeWatched()) { + dbusWatch->stopWatching(); + } + dbus_watch_set_data(libdbusWatch, NULL, NULL); + delete dbusWatch; +} + +void DBusConnection::onToggleWatch(::DBusWatch* libdbusWatch, void* data) { + assert(static_cast<WatchContext*>(data)); + + DBusWatch* dbusWatch = static_cast<DBusWatch*>(dbus_watch_get_data(libdbusWatch)); + + if (dbusWatch->isReadyToBeWatched()) { + dbusWatch->startWatching(); + } else { + dbusWatch->stopWatching(); + } +} + + +dbus_bool_t DBusConnection::onAddTimeout(::DBusTimeout* libdbusTimeout, void* data) { + std::weak_ptr<MainLoopContext>* mainloop = static_cast<std::weak_ptr<MainLoopContext>*>(data); + assert(mainloop); + + DBusTimeout* dbusTimeout = new DBusTimeout(libdbusTimeout, *mainloop); + dbus_timeout_set_data(libdbusTimeout, dbusTimeout, NULL); + + if (dbusTimeout->isReadyToBeMonitored()) { + dbusTimeout->startMonitoring(); + } + + return TRUE; +} + +void DBusConnection::onRemoveTimeout(::DBusTimeout* libdbusTimeout, void* data) { + assert(static_cast<std::weak_ptr<MainLoopContext>*>(data)); + + DBusTimeout* dbusTimeout = static_cast<DBusTimeout*>(dbus_timeout_get_data(libdbusTimeout)); + dbusTimeout->stopMonitoring(); + dbus_timeout_set_data(libdbusTimeout, NULL, NULL); + delete dbusTimeout; +} + +void DBusConnection::onToggleTimeout(::DBusTimeout* dbustimeout, void* data) { + assert(static_cast<std::weak_ptr<MainLoopContext>*>(data)); + + DBusTimeout* timeout = static_cast<DBusTimeout*>(dbus_timeout_get_data(dbustimeout)); + + if (timeout->isReadyToBeMonitored()) { + timeout->startMonitoring(); + } else { + timeout->stopMonitoring(); + } +} + + +bool DBusConnection::connect(bool startDispatchThread) { DBusError dbusError; - return connect(dbusError); + return connect(dbusError, startDispatchThread); } -bool DBusConnection::connect(DBusError& dbusError) { +bool DBusConnection::connect(DBusError& dbusError, bool startDispatchThread) { assert(!dbusError); - if (isConnected()) + if (isConnected()) { return true; + } const ::DBusBusType libdbusType = static_cast<DBusBusType>(busType_); @@ -114,8 +258,10 @@ bool DBusConnection::connect(DBusError& dbusError) { initLibdbusSignalFilterAfterConnect(); - stopDispatching_ = false; - dispatchThread_ = std::thread(&DBusConnection::dispatch, this, this->shared_from_this()); + if(startDispatchThread) { + dispatchThread_ = new std::thread(&DBusConnection::dispatch, this, this->shared_from_this()); + } + stopDispatching_ = !startDispatchThread; dbusConnectionStatusEvent_.notifyListeners(AvailabilityStatus::AVAILABLE); @@ -135,12 +281,16 @@ void DBusConnection::disconnect() { dbus_connection_close(libdbusConnection_); - //It is possible for the disconnect to be called from within a callback, i.e. from within the dispatch - //thread. Self-join is prevented this way. - if (dispatchThread_.joinable() && std::this_thread::get_id() != dispatchThread_.get_id()) { - dispatchThread_.join(); - } else { - dispatchThread_.detach(); + if(dispatchThread_) { + //It is possible for the disconnect to be called from within a callback, i.e. from within the dispatch + //thread. Self-join is prevented this way. + if (dispatchThread_->joinable() && std::this_thread::get_id() != dispatchThread_->get_id()) { + dispatchThread_->join(); + } else { + dispatchThread_->detach(); + } + delete dispatchThread_; + dispatchThread_ = NULL; } dbus_connection_unref(libdbusConnection_); @@ -304,13 +454,24 @@ DBusMessage DBusConnection::sendDBusMessageWithReplyAndBlock(const DBusMessage& resumeDispatching(); - if (dbusError) + if (dbusError) { return DBusMessage(); + } const bool increaseLibdbusMessageReferenceCount = false; return DBusMessage(libdbusMessageReply, increaseLibdbusMessageReferenceCount); } + +bool DBusConnection::singleDispatch() { + return (dbus_connection_dispatch(libdbusConnection_) == DBUS_DISPATCH_DATA_REMAINS); +} + +bool DBusConnection::isDispatchReady() { + return (dbus_connection_get_dispatch_status(libdbusConnection_) == DBUS_DISPATCH_DATA_REMAINS); +} + + DBusProxyConnection::DBusSignalHandlerToken DBusConnection::addSignalMemberHandler(const std::string& objectPath, const std::string& interfaceName, const std::string& interfaceMemberName, diff --git a/src/CommonAPI/DBus/DBusConnection.h b/src/CommonAPI/DBus/DBusConnection.h index 06ad2a9..79055ef 100644 --- a/src/CommonAPI/DBus/DBusConnection.h +++ b/src/CommonAPI/DBus/DBusConnection.h @@ -11,10 +11,10 @@ #include "DBusDaemonProxy.h" #include "DBusServiceRegistry.h" #include "DBusObjectManager.h" +#include "DBusMainLoopContext.h" #include <dbus/dbus.h> - namespace CommonAPI { namespace DBus { @@ -32,69 +32,73 @@ class DBusConnectionStatusEvent: public DBusProxyConnection::ConnectionStatusEve DBusConnection* dbusConnection_; }; +struct WatchContext { + WatchContext(std::weak_ptr<MainLoopContext> mainLoopContext, DispatchSource* dispatchSource) : + mainLoopContext_(mainLoopContext), dispatchSource_(dispatchSource) { + } + + std::weak_ptr<MainLoopContext> mainLoopContext_; + DispatchSource* dispatchSource_; +}; class DBusConnection: public DBusProxyConnection, public std::enable_shared_from_this<DBusConnection> { public: - enum BusType { - SESSION = DBUS_BUS_SESSION, - SYSTEM = DBUS_BUS_SYSTEM, - STARTER = DBUS_BUS_STARTER, - WRAPPED - }; + enum BusType { + SESSION = DBUS_BUS_SESSION, SYSTEM = DBUS_BUS_SYSTEM, STARTER = DBUS_BUS_STARTER, WRAPPED + }; - DBusConnection(BusType busType); + DBusConnection(BusType busType); - inline static std::shared_ptr<DBusConnection> getBus(const BusType& busType); - inline static std::shared_ptr<DBusConnection> wrapLibDBus(::DBusConnection* libDbusConnection); - inline static std::shared_ptr<DBusConnection> getSessionBus(); - inline static std::shared_ptr<DBusConnection> getSystemBus(); - inline static std::shared_ptr<DBusConnection> getStarterBus(); + inline static std::shared_ptr<DBusConnection> getBus(const BusType& busType); + inline static std::shared_ptr<DBusConnection> wrapLibDBus(::DBusConnection* libDbusConnection); + inline static std::shared_ptr<DBusConnection> getSessionBus(); + inline static std::shared_ptr<DBusConnection> getSystemBus(); + inline static std::shared_ptr<DBusConnection> getStarterBus(); - DBusConnection(const DBusConnection&) = delete; - DBusConnection(::DBusConnection* libDbusConnection); + DBusConnection(const DBusConnection&) = delete; + DBusConnection(::DBusConnection* libDbusConnection); - DBusConnection& operator=(const DBusConnection&) = delete; - virtual ~DBusConnection(); + DBusConnection& operator=(const DBusConnection&) = delete; + virtual ~DBusConnection(); - BusType getBusType() const; + BusType getBusType() const; - bool connect(); - bool connect(DBusError& dbusError); - void disconnect(); + bool connect(bool startDispatchThread = true); + bool connect(DBusError& dbusError, bool startDispatchThread = true); + void disconnect(); - virtual bool isConnected() const; + virtual bool isConnected() const; - virtual ConnectionStatusEvent& getConnectionStatusEvent(); + virtual ConnectionStatusEvent& getConnectionStatusEvent(); - virtual bool requestServiceNameAndBlock(const std::string& serviceName) const; - virtual bool releaseServiceName(const std::string& serviceName) const; + virtual bool requestServiceNameAndBlock(const std::string& serviceName) const; + virtual bool releaseServiceName(const std::string& serviceName) const; - bool sendDBusMessage(const DBusMessage& dbusMessage, uint32_t* allocatedSerial = NULL) const; + bool sendDBusMessage(const DBusMessage& dbusMessage, uint32_t* allocatedSerial = NULL) const; - static const int kDefaultSendTimeoutMs = 100 * 1000; + static const int kDefaultSendTimeoutMs = 5000; - std::future<CallStatus> sendDBusMessageWithReplyAsync( - const DBusMessage& dbusMessage, - std::unique_ptr<DBusMessageReplyAsyncHandler> dbusMessageReplyAsyncHandler, - int timeoutMilliseconds = kDefaultSendTimeoutMs) const; + std::future<CallStatus> sendDBusMessageWithReplyAsync( + const DBusMessage& dbusMessage, + std::unique_ptr<DBusMessageReplyAsyncHandler> dbusMessageReplyAsyncHandler, + int timeoutMilliseconds = kDefaultSendTimeoutMs) const; - DBusMessage sendDBusMessageWithReplyAndBlock(const DBusMessage& dbusMessage, - DBusError& dbusError, - int timeoutMilliseconds = kDefaultSendTimeoutMs) const; + DBusMessage sendDBusMessageWithReplyAndBlock(const DBusMessage& dbusMessage, + DBusError& dbusError, + int timeoutMilliseconds = kDefaultSendTimeoutMs) const; - DBusSignalHandlerToken addSignalMemberHandler(const std::string& objectPath, - const std::string& interfaceName, - const std::string& interfaceMemberName, - const std::string& interfaceMemberSignature, - DBusSignalHandler* dbusSignalHandler); + DBusSignalHandlerToken addSignalMemberHandler(const std::string& objectPath, + const std::string& interfaceName, + const std::string& interfaceMemberName, + const std::string& interfaceMemberSignature, + DBusSignalHandler* dbusSignalHandler); - void registerObjectPath(const std::string& objectPath); + void registerObjectPath(const std::string& objectPath); + void unregisterObjectPath(const std::string& objectPath); - void unregisterObjectPath(const std::string& objectPath); + void removeSignalMemberHandler(const DBusSignalHandlerToken& dbusSignalHandlerToken); - void removeSignalMemberHandler(const DBusSignalHandlerToken& dbusSignalHandlerToken); - - bool readWriteDispatch(int timeoutMilliseconds = -1); + bool readWriteDispatch(int timeoutMilliseconds = -1); virtual const std::shared_ptr<DBusServiceRegistry> getDBusServiceRegistry(); virtual const std::shared_ptr<DBusObjectManager> getDBusObjectManager(); @@ -102,65 +106,82 @@ class DBusConnection: public DBusProxyConnection, public std::enable_shared_from void setObjectPathMessageHandler(DBusObjectPathMessageHandler); bool isObjectPathMessageHandlerSet(); + virtual bool attachMainLoopContext(std::weak_ptr<MainLoopContext>); + + bool isDispatchReady(); + bool singleDispatch(); + private: void dispatch(std::shared_ptr<DBusConnection> selfReference); void suspendDispatching() const; void resumeDispatching() const; - std::thread dispatchThread_; + std::thread* dispatchThread_; bool stopDispatching_; + std::weak_ptr<MainLoopContext> mainLoopContext_; + DispatchSource* dispatchSource_; + WatchContext* watchContext_; + mutable bool pauseDispatching_; mutable std::mutex dispatchSuspendLock_; - void addLibdbusSignalMatchRule(const std::string& objectPath, - const std::string& interfaceName, - const std::string& interfaceMemberName); + void addLibdbusSignalMatchRule(const std::string& objectPath, + const std::string& interfaceName, + const std::string& interfaceMemberName); - void removeLibdbusSignalMatchRule(const std::string& objectPath, - const std::string& interfaceName, - const std::string& interfaceMemberName); + void removeLibdbusSignalMatchRule(const std::string& objectPath, + const std::string& interfaceName, + const std::string& interfaceMemberName); - void initLibdbusObjectPathHandlerAfterConnect(); + void initLibdbusSignalFilterAfterConnect(); + ::DBusHandlerResult onLibdbusSignalFilter(::DBusMessage* libdbusMessage); - void initLibdbusSignalFilterAfterConnect(); + void initLibdbusObjectPathHandlerAfterConnect(); + ::DBusHandlerResult onLibdbusObjectPathMessage(::DBusMessage* libdbusMessage); - ::DBusHandlerResult onLibdbusObjectPathMessage(::DBusMessage* libdbusMessage); + static void onLibdbusPendingCallNotifyThunk(::DBusPendingCall* libdbusPendingCall, void* userData); + static void onLibdbusDataCleanup(void* userData); - ::DBusHandlerResult onLibdbusSignalFilter(::DBusMessage* libdbusMessage); + static ::DBusHandlerResult onLibdbusObjectPathMessageThunk(::DBusConnection* libdbusConnection, + ::DBusMessage* libdbusMessage, + void* userData); - static void onLibdbusPendingCallNotifyThunk(::DBusPendingCall* libdbusPendingCall, void* userData); - static void onLibdbusDataCleanup(void* userData); + static ::DBusHandlerResult onLibdbusSignalFilterThunk(::DBusConnection* libdbusConnection, + ::DBusMessage* libdbusMessage, + void* userData); - static ::DBusHandlerResult onLibdbusObjectPathMessageThunk(::DBusConnection* libdbusConnection, - ::DBusMessage* libdbusMessage, - void* userData); + static dbus_bool_t onAddWatch(::DBusWatch* libdbusWatch, void* data); + static void onRemoveWatch(::DBusWatch* libdbusWatch, void* data); + static void onToggleWatch(::DBusWatch* libdbusWatch, void* data); - static ::DBusHandlerResult onLibdbusSignalFilterThunk(::DBusConnection* libdbusConnection, - ::DBusMessage* libdbusMessage, - void* userData); + static dbus_bool_t onAddTimeout(::DBusTimeout* dbus_timeout, void* data); + static void onRemoveTimeout(::DBusTimeout* dbus_timeout, void* data); + static void onToggleTimeout(::DBusTimeout* dbus_timeout, void* data); - BusType busType_; + static void onWakeupMainContext(void* data); - ::DBusConnection* libdbusConnection_; - std::mutex libdbusConnectionGuard_; - std::mutex signalGuard_; + ::DBusConnection* libdbusConnection_; + std::mutex libdbusConnectionGuard_; + std::mutex signalGuard_; std::mutex objectManagerGuard_; std::mutex serviceRegistryGuard_; - std::weak_ptr<DBusServiceRegistry> dbusServiceRegistry_; + BusType busType_; + + std::weak_ptr<DBusServiceRegistry> dbusServiceRegistry_; std::shared_ptr<DBusObjectManager> dbusObjectManager_; - DBusConnectionStatusEvent dbusConnectionStatusEvent_; + DBusConnectionStatusEvent dbusConnectionStatusEvent_; - typedef std::tuple<std::string, std::string, std::string> DBusSignalMatchRuleTuple; - typedef std::pair<uint32_t, std::string> DBusSignalMatchRuleMapping; - typedef std::unordered_map<DBusSignalMatchRuleTuple, DBusSignalMatchRuleMapping> DBusSignalMatchRulesMap; - DBusSignalMatchRulesMap dbusSignalMatchRulesMap_; + typedef std::tuple<std::string, std::string, std::string> DBusSignalMatchRuleTuple; + typedef std::pair<uint32_t, std::string> DBusSignalMatchRuleMapping; + typedef std::unordered_map<DBusSignalMatchRuleTuple, DBusSignalMatchRuleMapping> DBusSignalMatchRulesMap; + DBusSignalMatchRulesMap dbusSignalMatchRulesMap_; DBusSignalHandlerTable dbusSignalHandlerTable_; - // referenceCount, objectPath + // objectPath, referenceCount typedef std::unordered_map<std::string, uint32_t> LibdbusRegisteredObjectPathHandlersTable; LibdbusRegisteredObjectPathHandlersTable libdbusRegisteredObjectPaths_; @@ -170,7 +191,7 @@ class DBusConnection: public DBusProxyConnection, public std::enable_shared_from }; std::shared_ptr<DBusConnection> DBusConnection::getBus(const BusType& busType) { - return std::make_shared<DBusConnection>(busType); + return std::make_shared<DBusConnection>(busType); } std::shared_ptr<DBusConnection> DBusConnection::wrapLibDBus(::DBusConnection* libDbusConnection) { @@ -178,18 +199,17 @@ std::shared_ptr<DBusConnection> DBusConnection::wrapLibDBus(::DBusConnection* li } std::shared_ptr<DBusConnection> DBusConnection::getSessionBus() { - return getBus(BusType::SESSION); + return getBus(BusType::SESSION); } std::shared_ptr<DBusConnection> DBusConnection::getSystemBus() { - return getBus(BusType::SYSTEM); + return getBus(BusType::SYSTEM); } std::shared_ptr<DBusConnection> DBusConnection::getStarterBus() { - return getBus(BusType::STARTER); + return getBus(BusType::STARTER); } - } // namespace DBus } // namespace CommonAPI diff --git a/src/CommonAPI/DBus/DBusFactory.cpp b/src/CommonAPI/DBus/DBusFactory.cpp index f45e9b7..c75a393 100644 --- a/src/CommonAPI/DBus/DBusFactory.cpp +++ b/src/CommonAPI/DBus/DBusFactory.cpp @@ -4,6 +4,7 @@ * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + #include "DBusProxy.h" #include "DBusConnection.h" #include "DBusFactory.h" @@ -20,6 +21,7 @@ namespace CommonAPI { namespace DBus { + std::unordered_map<std::string, DBusProxyFactoryFunction>* registeredProxyFactoryFunctions_; std::unordered_map<std::string, DBusAdapterFactoryFunction>* registeredAdapterFactoryFunctions_; @@ -39,12 +41,16 @@ void DBusFactory::registerAdapterFactoryMethod(std::string interfaceName, DBusAd } - -DBusFactory::DBusFactory(std::shared_ptr<Runtime> runtime, const MiddlewareInfo* middlewareInfo) : +DBusFactory::DBusFactory(std::shared_ptr<Runtime> runtime, const MiddlewareInfo* middlewareInfo, std::shared_ptr<MainLoopContext> mainLoopContext) : CommonAPI::Factory(runtime, middlewareInfo), dbusConnection_(CommonAPI::DBus::DBusConnection::getSessionBus()), - acquiredConnectionName_("") { - dbusConnection_->connect(); + acquiredConnectionName_(""), + mainLoopContext_(mainLoopContext) { + bool startDispatchThread = !mainLoopContext_; + dbusConnection_->connect(startDispatchThread); + if(mainLoopContext_) { + dbusConnection_->attachMainLoopContext(mainLoopContext); + } } @@ -139,8 +145,7 @@ bool DBusFactory::registerAdapter(std::shared_ptr<StubBase> stubBase, if(!dbusStubAdapter) { return false; } - std::string address = domain + ":" + serviceName + ":" + participantId; - if(registeredServices_.insert( {std::move(address), dbusStubAdapter} ).second) { + if(registeredServices_.insert( {std::move(commonApiAddress), dbusStubAdapter} ).second) { dbusStubAdapter->init(); return true; } diff --git a/src/CommonAPI/DBus/DBusFactory.h b/src/CommonAPI/DBus/DBusFactory.h index a3edfdc..2b1a813 100644 --- a/src/CommonAPI/DBus/DBusFactory.h +++ b/src/CommonAPI/DBus/DBusFactory.h @@ -18,11 +18,14 @@ namespace CommonAPI { namespace DBus { +class DBusMainLoopContext; + typedef std::shared_ptr<DBusProxy> (*DBusProxyFactoryFunction) (const std::string& commonApiAddress, const std::string& interfaceName, const std::string& busName, const std::string& objectPath, const std::shared_ptr<DBusProxyConnection>& dbusProxyConnection); + typedef std::shared_ptr<DBusStubAdapter> (*DBusAdapterFactoryFunction) (const std::string& commonApiAddress, const std::string& interfaceName, const std::string& busName, @@ -32,7 +35,7 @@ typedef std::shared_ptr<DBusStubAdapter> (*DBusAdapterFactoryFunction) (const st class DBusFactory: public Factory { public: - DBusFactory(std::shared_ptr<Runtime> runtime, const MiddlewareInfo* middlewareInfo); + DBusFactory(std::shared_ptr<Runtime> runtime, const MiddlewareInfo* middlewareInfo, std::shared_ptr<MainLoopContext> mainLoopContext = std::shared_ptr<MainLoopContext>(NULL)); virtual ~DBusFactory(); static void registerProxyFactoryMethod(std::string interfaceName, DBusProxyFactoryFunction proxyFactoryFunction); @@ -53,6 +56,7 @@ class DBusFactory: public Factory { std::shared_ptr<CommonAPI::DBus::DBusConnection> dbusConnection_; std::string acquiredConnectionName_; std::unordered_map<std::string, std::shared_ptr<DBusStubAdapter>> registeredServices_; + std::shared_ptr<MainLoopContext> mainLoopContext_; }; } // namespace DBus diff --git a/src/CommonAPI/DBus/DBusMainLoopContext.cpp b/src/CommonAPI/DBus/DBusMainLoopContext.cpp new file mode 100644 index 0000000..0a0908c --- /dev/null +++ b/src/CommonAPI/DBus/DBusMainLoopContext.cpp @@ -0,0 +1,143 @@ +/* Copyright (C) 2013 BMW Group + * Author: Manfred Bathelt (manfred.bathelt@bmw.de) + * Author: Juergen Gehring (juergen.gehring@bmw.de) + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + + +#include "DBusMainLoopContext.h" +#include "DBusConnection.h" + +#include <poll.h> +#include <chrono> + + +namespace CommonAPI { +namespace DBus { + + +DBusDispatchSource::DBusDispatchSource(DBusProxyConnection* dbusConnection): + dbusConnection_(dbusConnection) { +} + +DBusDispatchSource::~DBusDispatchSource() { +} + +bool DBusDispatchSource::prepare(int64_t& timeout) { + return dbusConnection_->isDispatchReady(); +} + +bool DBusDispatchSource::check() { + return dbusConnection_->isDispatchReady(); +} + +bool DBusDispatchSource::dispatch() { + return dbusConnection_->singleDispatch(); +} + + +DBusWatch::DBusWatch(::DBusWatch* libdbusWatch, std::weak_ptr<MainLoopContext>& mainLoopContext): + libdbusWatch_(libdbusWatch), + mainLoopContext_(mainLoopContext), + channelFlags_(0) { + assert(libdbusWatch_); +} + +bool DBusWatch::isReadyToBeWatched() { + return dbus_watch_get_enabled(libdbusWatch_); +} + +void DBusWatch::startWatching() { + channelFlags_ = dbus_watch_get_flags(libdbusWatch_); + short int pollFlags = POLLERR | POLLHUP; + if(channelFlags_ & DBUS_WATCH_READABLE) { + pollFlags |= POLLIN; + } + if(channelFlags_ & DBUS_WATCH_WRITABLE) { + pollFlags |= POLLOUT; + } + + pollFileDescriptor_.fd = dbus_watch_get_unix_fd(libdbusWatch_); + pollFileDescriptor_.events = pollFlags; + pollFileDescriptor_.revents = 0; + + auto lockedContext = mainLoopContext_.lock(); + assert(lockedContext); + lockedContext->registerWatch(this); +} + +void DBusWatch::stopWatching() { + auto lockedContext = mainLoopContext_.lock(); + assert(lockedContext); + lockedContext->deregisterWatch(this); +} + +const pollfd& DBusWatch::getAssociatedFileDescriptor() { + return pollFileDescriptor_; +} + +//XXX Default hierfür die revent-flags? +void DBusWatch::dispatch(unsigned int eventFlags) { + dbus_watch_handle(libdbusWatch_, eventFlags); +} + +const std::vector<DispatchSource*>& DBusWatch::getDependentDispatchSources() { + return dependentDispatchSources_; +} + +void DBusWatch::addDependentDispatchSource(DispatchSource* dispatchSource) { + dependentDispatchSources_.push_back(dispatchSource); +} + + +DBusTimeout::DBusTimeout(::DBusTimeout* libdbusTimeout, std::weak_ptr<MainLoopContext>& mainLoopContext) : + libdbusTimeout_(libdbusTimeout), + mainLoopContext_(mainLoopContext), + dueTimeInMs_(TIMEOUT_INFINITE) { +} + +bool DBusTimeout::isReadyToBeMonitored() { + return dbus_timeout_get_enabled(libdbusTimeout_); +} + +void DBusTimeout::startMonitoring() { + auto lockedContext = mainLoopContext_.lock(); + assert(lockedContext); + recalculateDueTime(); + lockedContext->registerTimeoutSource(this); +} + +void DBusTimeout::stopMonitoring() { + dueTimeInMs_ = TIMEOUT_INFINITE; + auto lockedContext = mainLoopContext_.lock(); + assert(lockedContext); + lockedContext->deregisterTimeoutSource(this); +} + +bool DBusTimeout::dispatch() { + recalculateDueTime(); + dbus_timeout_handle(libdbusTimeout_); + return true; +} + +int64_t DBusTimeout::getTimeoutInterval() const { + return dbus_timeout_get_interval(libdbusTimeout_); +} + +int64_t DBusTimeout::getReadyTime() const { + return dueTimeInMs_; +} + +void DBusTimeout::recalculateDueTime() { + if(dbus_timeout_get_enabled(libdbusTimeout_)) { + unsigned int intervalInMs = dbus_timeout_get_interval(libdbusTimeout_); + dueTimeInMs_ = getCurrentTimeInMs() + intervalInMs; + } else { + dueTimeInMs_ = TIMEOUT_INFINITE; + } +} + + +} // namespace DBus +} // namespace CommonAPI diff --git a/src/CommonAPI/DBus/DBusMainLoopContext.h b/src/CommonAPI/DBus/DBusMainLoopContext.h new file mode 100644 index 0000000..f158758 --- /dev/null +++ b/src/CommonAPI/DBus/DBusMainLoopContext.h @@ -0,0 +1,94 @@ +/* Copyright (C) 2013 BMW Group + * Author: Manfred Bathelt (manfred.bathelt@bmw.de) + * Author: Juergen Gehring (juergen.gehring@bmw.de) + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef DBUS_MAINLOOPCONTEXT_H_ +#define DBUS_MAINLOOPCONTEXT_H_ + +#include <list> +#include <memory> +#include <poll.h> + +#include <dbus/dbus.h> + +#include <CommonAPI/MainLoopContext.h> + + +namespace CommonAPI { +namespace DBus { + +class DBusProxyConnection; + + + +class DBusDispatchSource: public DispatchSource { + public: + DBusDispatchSource(DBusProxyConnection* dbusConnection); + ~DBusDispatchSource(); + + bool prepare(int64_t& timeout); + bool check(); + bool dispatch(); + + private: + DBusProxyConnection* dbusConnection_; +}; + +class DBusWatch: public Watch { + public: + DBusWatch(::DBusWatch* libdbusWatch, std::weak_ptr<MainLoopContext>& mainLoopContext); + + bool isReadyToBeWatched(); + void startWatching(); + void stopWatching(); + + void dispatch(unsigned int eventFlags); + + const pollfd& getAssociatedFileDescriptor(); + + const std::vector<DispatchSource*>& getDependentDispatchSources(); + void addDependentDispatchSource(DispatchSource* dispatchSource); + + private: + bool isReady(); + + ::DBusWatch* libdbusWatch_; + pollfd pollFileDescriptor_; + std::vector<DispatchSource*> dependentDispatchSources_; + + std::weak_ptr<MainLoopContext> mainLoopContext_; + + //XXX Necessary? Are they not covered by the fd-events? + unsigned int channelFlags_; +}; + + +class DBusTimeout: public Timeout { + public: + DBusTimeout(::DBusTimeout* libdbusTimeout, std::weak_ptr<MainLoopContext>& mainLoopContext); + + bool isReadyToBeMonitored(); + void startMonitoring(); + void stopMonitoring(); + + bool dispatch(); + + int64_t getTimeoutInterval() const; + int64_t getReadyTime() const; + + private: + void recalculateDueTime(); + + int64_t dueTimeInMs_; + ::DBusTimeout* libdbusTimeout_; + std::weak_ptr<MainLoopContext> mainLoopContext_; +}; + + +} // namespace DBus +} // namespace CommonAPI + +#endif diff --git a/src/CommonAPI/DBus/DBusProxyConnection.h b/src/CommonAPI/DBus/DBusProxyConnection.h index 8ad6b32..f47c700 100644 --- a/src/CommonAPI/DBus/DBusProxyConnection.h +++ b/src/CommonAPI/DBus/DBusProxyConnection.h @@ -59,38 +59,42 @@ class DBusProxyConnection { typedef Event<AvailabilityStatus> ConnectionStatusEvent; - virtual ~DBusProxyConnection() { } + virtual ~DBusProxyConnection() { + } - virtual bool isConnected() const = 0; + virtual bool isConnected() const = 0; - virtual ConnectionStatusEvent& getConnectionStatusEvent() = 0; + virtual ConnectionStatusEvent& getConnectionStatusEvent() = 0; - virtual bool sendDBusMessage(const DBusMessage& dbusMessage, uint32_t* allocatedSerial = NULL) const = 0; + virtual bool sendDBusMessage(const DBusMessage& dbusMessage, uint32_t* allocatedSerial = NULL) const = 0; - static const int kDefaultSendTimeoutMs = 100 * 1000; + static const int kDefaultSendTimeoutMs = 100 * 1000; - virtual std::future<CallStatus> sendDBusMessageWithReplyAsync( - const DBusMessage& dbusMessage, - std::unique_ptr<DBusMessageReplyAsyncHandler> dbusMessageReplyAsyncHandler, - int timeoutMilliseconds = kDefaultSendTimeoutMs) const = 0; + virtual std::future<CallStatus> sendDBusMessageWithReplyAsync( + const DBusMessage& dbusMessage, + std::unique_ptr<DBusMessageReplyAsyncHandler> dbusMessageReplyAsyncHandler, + int timeoutMilliseconds = kDefaultSendTimeoutMs) const = 0; - virtual DBusMessage sendDBusMessageWithReplyAndBlock( - const DBusMessage& dbusMessage, - DBusError& dbusError, - int timeoutMilliseconds = kDefaultSendTimeoutMs) const = 0; + virtual DBusMessage sendDBusMessageWithReplyAndBlock( + const DBusMessage& dbusMessage, + DBusError& dbusError, + int timeoutMilliseconds = kDefaultSendTimeoutMs) const = 0; - virtual DBusSignalHandlerToken addSignalMemberHandler( - const std::string& objectPath, - const std::string& interfaceName, - const std::string& interfaceMemberName, - const std::string& interfaceMemberSignature, - DBusSignalHandler* dbusSignalHandler) = 0; + virtual DBusSignalHandlerToken addSignalMemberHandler( + const std::string& objectPath, + const std::string& interfaceName, + const std::string& interfaceMemberName, + const std::string& interfaceMemberSignature, + DBusSignalHandler* dbusSignalHandler) = 0; - virtual void removeSignalMemberHandler(const DBusSignalHandlerToken& dbusSignalHandlerToken) = 0; + virtual void removeSignalMemberHandler(const DBusSignalHandlerToken& dbusSignalHandlerToken) = 0; virtual const std::shared_ptr<DBusServiceRegistry> getDBusServiceRegistry() = 0; virtual const std::shared_ptr<DBusObjectManager> getDBusObjectManager() = 0; + virtual bool isDispatchReady() = 0; + virtual bool singleDispatch() = 0; + virtual void registerObjectPath(const std::string& objectPath) = 0; virtual void unregisterObjectPath(const std::string& objectPath) = 0; diff --git a/src/CommonAPI/DBus/DBusRuntime.cpp b/src/CommonAPI/DBus/DBusRuntime.cpp index da1b272..a6d92db 100644 --- a/src/CommonAPI/DBus/DBusRuntime.cpp +++ b/src/CommonAPI/DBus/DBusRuntime.cpp @@ -23,8 +23,8 @@ std::shared_ptr<Runtime> DBusRuntime::getInstance() { return singleton_; } -std::shared_ptr<Factory> DBusRuntime::createFactory() { - auto factory = std::make_shared<DBusFactory>(this->shared_from_this(), &middlewareInfo_); +std::shared_ptr<Factory> DBusRuntime::createFactory(std::shared_ptr<MainLoopContext> mainLoopContext) { + auto factory = std::make_shared<DBusFactory>(this->shared_from_this(), &middlewareInfo_, mainLoopContext); return factory; } diff --git a/src/CommonAPI/DBus/DBusRuntime.h b/src/CommonAPI/DBus/DBusRuntime.h index b91f304..3784f91 100644 --- a/src/CommonAPI/DBus/DBusRuntime.h +++ b/src/CommonAPI/DBus/DBusRuntime.h @@ -18,7 +18,7 @@ class DBusRuntime: public Runtime, public std::enable_shared_from_this<DBusRunti public: static std::shared_ptr<Runtime> getInstance(); - std::shared_ptr<Factory> createFactory(); + std::shared_ptr<Factory> createFactory(std::shared_ptr<MainLoopContext> = std::shared_ptr<MainLoopContext>(NULL)); static const MiddlewareInfo middlewareInfo_; }; |