summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohannes Schanda <schanda@itestra.de>2013-05-06 12:08:35 +0200
committerGerrit Code Review <qqmthk1@lpmodthk02.bmwgroup.net>2013-05-06 12:08:35 +0200
commit8867ca4b3833f89bb1fae69f92d3a2cdac5d50b9 (patch)
tree64b01f280e4a5cc54a6325e2cd245b08c94b8d0f
parent215a5f2b9e7e295e54118837d7ba79276fc88f2d (diff)
parent0e1b727ec4b141d88a44067a8994b08294aa4d40 (diff)
downloadgenivi-common-api-dbus-runtime-8867ca4b3833f89bb1fae69f92d3a2cdac5d50b9.tar.gz
Merge "Added and integrated necessary D-Bus Mainloop Context"
-rw-r--r--Makefile.am170
-rw-r--r--src/CommonAPI/DBus/DBusConnection.cpp191
-rw-r--r--src/CommonAPI/DBus/DBusConnection.h178
-rw-r--r--src/CommonAPI/DBus/DBusFactory.cpp17
-rw-r--r--src/CommonAPI/DBus/DBusFactory.h6
-rw-r--r--src/CommonAPI/DBus/DBusMainLoopContext.cpp143
-rw-r--r--src/CommonAPI/DBus/DBusMainLoopContext.h94
-rw-r--r--src/CommonAPI/DBus/DBusProxyConnection.h44
-rw-r--r--src/CommonAPI/DBus/DBusRuntime.cpp4
-rw-r--r--src/CommonAPI/DBus/DBusRuntime.h2
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_;
};