summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJürgen Gehring <Juergen.Gehring@bmw.de>2016-11-04 09:17:16 -0700
committerJürgen Gehring <Juergen.Gehring@bmw.de>2016-11-04 09:17:16 -0700
commitd727692b9af85cea85e1bac7c98b920a0b14800a (patch)
tree648111fc841701de0120d53f71f9b412f71cfc40
parentde8b3104eaa00475abc23bd861e7f8c3105d9553 (diff)
downloadgenivi-common-api-dbus-runtime-d727692b9af85cea85e1bac7c98b920a0b14800a.tar.gz
CommonAPI-D-Bus 3.1.103.1.10
-rw-r--r--CHANGES20
-rw-r--r--CMakeLists.txt6
-rw-r--r--INSTALL70
-rw-r--r--README3
-rw-r--r--include/CommonAPI/DBus/DBusConnection.hpp24
-rw-r--r--include/CommonAPI/DBus/DBusErrorEvent.hpp131
-rw-r--r--include/CommonAPI/DBus/DBusEvent.hpp60
-rw-r--r--include/CommonAPI/DBus/DBusFreedesktopAttribute.hpp64
-rw-r--r--include/CommonAPI/DBus/DBusInstanceAvailabilityStatusChangedEvent.hpp16
-rw-r--r--include/CommonAPI/DBus/DBusMainLoopContext.hpp2
-rw-r--r--include/CommonAPI/DBus/DBusMessage.hpp2
-rw-r--r--include/CommonAPI/DBus/DBusProxy.hpp29
-rw-r--r--include/CommonAPI/DBus/DBusProxyAsyncCallbackHandler.hpp152
-rw-r--r--include/CommonAPI/DBus/DBusProxyAsyncSignalMemberCallbackHandler.hpp10
-rw-r--r--include/CommonAPI/DBus/DBusProxyBase.hpp8
-rw-r--r--include/CommonAPI/DBus/DBusProxyConnection.hpp13
-rw-r--r--include/CommonAPI/DBus/DBusProxyHelper.hpp194
-rw-r--r--include/CommonAPI/DBus/DBusSelectiveEvent.hpp6
-rw-r--r--include/CommonAPI/DBus/DBusServiceRegistry.hpp16
-rw-r--r--include/CommonAPI/DBus/DBusStubAdapterHelper.hpp237
-rw-r--r--include/murmurhash/MurmurHash3.h6
-rw-r--r--src/CommonAPI/DBus/DBusConnection.cpp168
-rw-r--r--src/CommonAPI/DBus/DBusFunctionalHash.cpp36
-rw-r--r--src/CommonAPI/DBus/DBusInstanceAvailabilityStatusChangedEvent.cpp49
-rwxr-xr-xsrc/CommonAPI/DBus/DBusMainLoop.cpp86
-rw-r--r--src/CommonAPI/DBus/DBusMainLoopContext.cpp240
-rw-r--r--src/CommonAPI/DBus/DBusMessage.cpp4
-rw-r--r--src/CommonAPI/DBus/DBusProxy.cpp59
-rw-r--r--src/CommonAPI/DBus/DBusProxyBase.cpp7
-rw-r--r--src/CommonAPI/DBus/DBusServiceRegistry.cpp73
-rw-r--r--src/dbus-patches/capi-dbus-send-with-reply-and-block-delete-reply-on-error.patch26
-rw-r--r--src/murmurhash/MurmurHash3.cpp40
-rw-r--r--src/pugixml/pugixml.cpp78
33 files changed, 1318 insertions, 617 deletions
diff --git a/CHANGES b/CHANGES
new file mode 100644
index 0000000..a1ba61b
--- /dev/null
+++ b/CHANGES
@@ -0,0 +1,20 @@
+Changes
+=======
+
+v3.1.10
+- If an 'DBusInstanceAvailabilityStatusChangedEvent' occurs and the manager proxy was deleted, a bad_weak_ptr occurs. This is now avoided by introducing a weak_ptr. If the weak_ptr can be locked, the manager proxy was not deleted yet.
+- Moved mutex lock in 'DBusMainLoop::registerWatch' to avoid deadlock.
+- The 'DBusSignalHandlers' were stored as raw pointers and this can cause crashes when the proxy was deleted. This is now replaced by storing a weak_ptr of the 'DBusSignalHandler'.
+- DBusFreeDesktopAttribute is now adjusted to use the new interface of freeDesktopGetCurrentValueForSignalListener in LegacyEvent.
+- Fixed availability problem with services <= CommonAPI 3.1.8 due to the extension of the CommonAPI address.
+- Check path correctness in managed callback (DBusServiceRegistry.cpp).
+- Remove clang compiler warnings.
+- Keep service registry map alive: During program cleanup, the global service registry map was deleted before the global variables to proxies were cleaned up. This caused problems when the proxy tried to access the map that was no longer there. Solution: keep a reference to the map in the service registry entry. This way the map is deleted only after the last service registry (and the last proxy) has been deleted.
+- Fixed THMainloopIndependence and THMainloopIntegration segfault. The problem is that a 'DBusQueueDispatchSource' has a pointer to its related 'DBusQueueWatch' as member variable and in the destructor of the dispatch source the watch is accessed. So a segfault can occur when the watch is deleted before the dispatch source.
+- Replaced polling mechanism in 'DBusMainLoop' from sockets to WSAEvents in combination with named pipes.
+- Added support for the DBus message type 'Error'. This needed the introduction of a new class ('DBusErrorEvent'), adaptions on proxy side ('DBusProxyHelper') and on stub side ('DBusStubAdapterHelper') and a libdbus patch that avoids the deletion of a message reply when an error occured / when an error reply was sent. This is necessary to deserialize the arguments of the error reply.
+
+
+
+
+
diff --git a/CMakeLists.txt b/CMakeLists.txt
index f65ecb0..9967698 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -10,7 +10,7 @@ PROJECT(libcommonapi-dbus)
# version of CommonAPI-DBus
SET( LIBCOMMONAPI_DBUS_MAJOR_VERSION 3 )
SET( LIBCOMMONAPI_DBUS_MINOR_VERSION 1 )
-SET( LIBCOMMONAPI_DBUS_PATCH_VERSION 9 )
+SET( LIBCOMMONAPI_DBUS_PATCH_VERSION 10 )
message(STATUS "Project name: ${PROJECT_NAME}")
@@ -123,9 +123,9 @@ message(STATUS "CMAKE_FIND_ROOT_PATH: ${CMAKE_FIND_ROOT_PATH}")
FIND_PACKAGE(PkgConfig)
FIND_PACKAGE(Threads REQUIRED)
if ("${USE_INSTALLED_COMMONAPI}" STREQUAL "ON")
- FIND_PACKAGE(CommonAPI 3.1.9 REQUIRED CONFIG NO_CMAKE_PACKAGE_REGISTRY)
+ FIND_PACKAGE(CommonAPI 3.1.10 REQUIRED CONFIG NO_CMAKE_PACKAGE_REGISTRY)
else()
- FIND_PACKAGE(CommonAPI 3.1.9 REQUIRED CONFIG NO_SYSTEM_ENVIRONMENT_PATH NO_CMAKE_SYSTEM_PATH)
+ FIND_PACKAGE(CommonAPI 3.1.10 REQUIRED CONFIG NO_SYSTEM_ENVIRONMENT_PATH NO_CMAKE_SYSTEM_PATH)
endif()
message(STATUS "CommonAPI_CONSIDERED_CONFIGS: ${CommonAPI_CONSIDERED_CONFIGS}")
diff --git a/INSTALL b/INSTALL
index 173169b..305df24 100644
--- a/INSTALL
+++ b/INSTALL
@@ -1,69 +1 @@
-= IPC CommonAPI D-Bus C++
-
-:doctitle: IPC CommonAPI D-Bus C++
-:version:
-
-== Copyright
-Copyright (C) 2015, Bayerische Motoren Werke Aktiengesellschaft (BMW AG).
-Copyright (C) 2015, GENIVI Alliance, Inc.
-
-This file is part of GENIVI Project IPC Common API C++.
-
-Contributions are licensed to the GENIVI Alliance under one or more Contribution License Agreements or MPL 2.0.
-
-== License
-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/.
-
-== Version
-{version}
-
-== CommonAPI D-Bus C++ User Guide
-The user guide can be found in the documentation directory of the CommonAPI-D-Bus-Tools project.
-
-== Further information
-Source code and latest news can be found at http://projects.genivi.org/commonapi/.
-
-== Build Instructions for Linux
-
-=== Patching libdbus
-
-CommonAPI-D-Bus needs some api functions of libdbus which are not available in actual libdbus versions. For these additional api functions it is necessary to patch the required libdbus version with all the patches in the directory src/dbus-patches. Use autotools to build libdbus.
-
-----
-$ wget http://dbus.freedesktop.org/releases/dbus/dbus-<VERSION>.tar.gz
-$ tar -xzf dbus-<VERSION>.tar.gz
-$ cd dbus-<VERSION>
-$ patch -p1 < </path/to/CommonAPI-D-Bus/src/dbus-patches/patch-names>.patch
-$ ./configure --prefix=</path to your preferred installation folder for patched libdbus>
-$ make -C dbus
-$ make -C dbus install
-$ make install-pkgconfigDATA
-----
-
-You can change the installation directory by the prefix option or you can let it uninstalled (skip the +make install+ commands).
-WARNING: Installing the patched libdbus to /usr/local can prevent your system from booting correctly at the next reboot.
-
-=== Build CommonAPI-D-Bus Runtime
-
-In order to build the CommonAPI-D-Bus Runtime library the pkgconfig files of the patched libdbus library must be added to the +PKG_CONFIG_PATH+.
-
-For example, if the patched libdbus library is available in /usr/local, set the +PKG_CONFIG_PATH+ variable as follows:
-
-----
-$ export PKG_CONFIG_PATH="/usr/local/lib/pkgconfig:$PKG_CONFIG_PATH"
-----
-
-Now use CMake to build the CommonAPI D-Bus runtime library. We assume that your source directory is +common-api-dbus-runtime+:
-
-----
-$ cd common-api-dbus-runtime
-$ mkdir build
-$ cd build
-$ cmake -D USE_INSTALLED_COMMONAPI=ON -D CMAKE_INSTALL_PREFIX=/usr/local ..
-$ make
-$ make install
-----
-
-You can change the installation directory by the CMake variable +CMAKE_INSTALL_PREFIX+ or you can let it uninstalled (skip the +make install+ command). If you want to use the uninstalled version of CommonAPI set the CMake variable USE_INSTALLED_COMMONAPI to OFF.
-
-For further build instructions (build for windows, build documentation, tests etc.) please refer to the CommonAPI D-Bus tutorial. \ No newline at end of file
+Please refer to README.md for the installation instructions.
diff --git a/README b/README
deleted file mode 100644
index c535eaa..0000000
--- a/README
+++ /dev/null
@@ -1,3 +0,0 @@
-This is CommonAPI-DBus 3.1.9
-
-Please refer to INSTALL for further information. \ No newline at end of file
diff --git a/include/CommonAPI/DBus/DBusConnection.hpp b/include/CommonAPI/DBus/DBusConnection.hpp
index b32274f..acb163f 100644
--- a/include/CommonAPI/DBus/DBusConnection.hpp
+++ b/include/CommonAPI/DBus/DBusConnection.hpp
@@ -156,27 +156,27 @@ public:
const CommonAPI::CallInfo *_info) const;
COMMONAPI_EXPORT virtual bool addObjectManagerSignalMemberHandler(const std::string& dbusBusName,
- DBusSignalHandler* dbusSignalHandler);
+ std::weak_ptr<DBusSignalHandler> dbusSignalHandler);
COMMONAPI_EXPORT virtual bool removeObjectManagerSignalMemberHandler(const std::string& dbusBusName,
- DBusSignalHandler* dbusSignalHandler);
+ DBusSignalHandler* dbusSignalHandler);
COMMONAPI_EXPORT DBusSignalHandlerToken addSignalMemberHandler(const std::string& objectPath,
const std::string& interfaceName,
const std::string& interfaceMemberName,
const std::string& inuint32_tterfaceMemberSignature,
- DBusSignalHandler* dbusSignalHandler,
+ std::weak_ptr<DBusSignalHandler> dbusSignalHandler,
const bool justAddFilter = false);
COMMONAPI_EXPORT void subscribeForSelectiveBroadcast(const std::string& objectPath,
const std::string& interfaceName,
const std::string& interfaceMemberName,
const std::string& interfaceMemberSignature,
- DBusSignalHandler* dbusSignalHandler,
+ std::weak_ptr<DBusSignalHandler> dbusSignalHandler,
DBusProxy* callingProxy,
uint32_t tag);
COMMONAPI_EXPORT void unsubscribeFromSelectiveBroadcast(const std::string& eventName,
- DBusProxyConnection::DBusSignalHandlerToken subscription,
+ DBusSignalHandlerToken subscription,
DBusProxy* callingProxy,
const DBusSignalHandler* dbusSignalHandler);
@@ -184,7 +184,7 @@ public:
COMMONAPI_EXPORT void unregisterObjectPath(const std::string& objectPath);
COMMONAPI_EXPORT bool removeSignalMemberHandler(const DBusSignalHandlerToken& dbusSignalHandlerToken,
- const DBusSignalHandler* dbusSignalHandler = NULL);
+ const DBusSignalHandler* dbusSignalHandler = NULL);
COMMONAPI_EXPORT bool readWriteDispatch(int timeoutMilliseconds = -1);
COMMONAPI_EXPORT virtual const std::shared_ptr<DBusObjectManager> getDBusObjectManager();
@@ -294,8 +294,11 @@ public:
COMMONAPI_EXPORT void enforceAsynchronousTimeouts() const;
COMMONAPI_EXPORT static const DBusObjectPathVTable* getDBusObjectPathVTable();
- COMMONAPI_EXPORT void sendPendingSelectiveSubscription(DBusProxy* proxy, std::string interfaceMemberName,
- DBusSignalHandler* dbusSignalHandler, uint32_t tag, std::string interfaceMemberSignature);
+ COMMONAPI_EXPORT void sendPendingSelectiveSubscription(DBusProxy* proxy,
+ std::string interfaceMemberName,
+ std::weak_ptr<DBusSignalHandler> dbusSignalHandler,
+ uint32_t tag,
+ std::string interfaceMemberSignature);
::DBusConnection* connection_;
mutable std::mutex connectionGuard_;
@@ -315,7 +318,8 @@ public:
DBusSignalHandlerTable dbusSignalHandlerTable_;
std::unordered_map<std::string, size_t> dbusObjectManagerSignalMatchRulesMap_;
- std::unordered_multimap<std::string, DBusSignalHandler*> dbusObjectManagerSignalHandlerTable_;
+ std::unordered_multimap<std::string, std::pair<DBusSignalHandler*,
+ std::weak_ptr<DBusSignalHandler>>> dbusObjectManagerSignalHandlerTable_;
std::mutex dbusObjectManagerSignalGuard_;
COMMONAPI_EXPORT bool addObjectManagerSignalMatchRule(const std::string& dbusBusName);
@@ -374,7 +378,7 @@ public:
mutable std::set<DBusMessageReplyAsyncHandler*> timeoutInfiniteAsyncHandlers_;
mutable std::mutex timeoutInfiniteAsyncHandlersMutex_;
- uint32_t activeConnections_;
+ int activeConnections_;
mutable std::mutex activeConnectionsMutex_;
bool isDisconnecting_;
diff --git a/include/CommonAPI/DBus/DBusErrorEvent.hpp b/include/CommonAPI/DBus/DBusErrorEvent.hpp
new file mode 100644
index 0000000..2256d33
--- /dev/null
+++ b/include/CommonAPI/DBus/DBusErrorEvent.hpp
@@ -0,0 +1,131 @@
+// Copyright (C) 2013-2015 Bayerische Motoren Werke Aktiengesellschaft (BMW AG)
+// 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/.
+
+#if !defined (COMMONAPI_INTERNAL_COMPILATION)
+#error "Only <CommonAPI/CommonAPI.hpp> can be included directly, this file may disappear or change contents."
+#endif
+
+#ifndef COMMONAPI_DBUS_DBUSERROREVENT_HPP_
+#define COMMONAPI_DBUS_DBUSERROREVENT_HPP_
+
+#include <CommonAPI/Event.hpp>
+
+#include <CommonAPI/DBus/DBusInputStream.hpp>
+
+namespace CommonAPI {
+namespace DBus {
+
+template <class...>
+class DBusErrorEvent;
+
+template<>
+class DBusErrorEvent<> : public Event<std::string> {
+public:
+ DBusErrorEvent(const std::string &_errorName) :
+ errorName_(_errorName) {}
+
+ DBusErrorEvent(const DBusErrorEvent &_source) :
+ errorName_(_source.errorName_) {}
+
+ virtual ~DBusErrorEvent() {}
+
+ inline const std::string & getErrorName() const {
+ return errorName_;
+ }
+
+ void notifyErrorEventListeners(const DBusMessage &_reply) {
+ (void)_reply;
+ this->notifyListeners(errorName_);
+ }
+
+private:
+ std::string errorName_;
+};
+
+template <
+ template <class...> class In_, class... InArgs_,
+ template <class...> class DeplIn_, class... DeplIn_Args>
+class DBusErrorEvent<
+ In_<InArgs_...>,
+ DeplIn_<DeplIn_Args...>> : public Event<std::string, InArgs_...> {
+public:
+ DBusErrorEvent(const std::string &_errorName,
+ const std::tuple<DeplIn_Args*...> &_in) :
+ errorName_(_errorName) {
+ initialize(typename make_sequence_range<sizeof...(DeplIn_Args), 0>::type(), _in);
+ }
+
+ DBusErrorEvent(const DBusErrorEvent &_source) :
+ errorName_(_source.errorName_),
+ in_(_source.in_) {}
+
+ virtual ~DBusErrorEvent() {}
+
+ inline const std::string & getErrorName() const {
+ return errorName_;
+ }
+
+ void notifyErrorEventListeners(const DBusMessage &_reply) {
+ deserialize(_reply, typename make_sequence_range<sizeof...(InArgs_), 0>::type());
+ }
+
+private:
+
+ template <int... DeplIn_ArgIndices>
+ inline void initialize(index_sequence<DeplIn_ArgIndices...>, const std::tuple<DeplIn_Args*...> &_in) {
+ in_ = std::make_tuple(std::get<DeplIn_ArgIndices>(_in)...);
+ }
+
+ template <int... InArgIndices_>
+ void deserialize(const DBusMessage &_reply,
+ index_sequence<InArgIndices_...>) {
+ if (sizeof...(InArgs_) > 0) {
+ DBusInputStream dbusInputStream(_reply);
+ const bool success = DBusSerializableArguments<CommonAPI::Deployable<InArgs_, DeplIn_Args>...>::deserialize(dbusInputStream, std::get<InArgIndices_>(in_)...);
+ if (!success)
+ return;
+ this->notifyListeners(errorName_, std::move(std::get<InArgIndices_>(in_).getValue())...);
+ }
+ }
+
+ std::string errorName_;
+ std::tuple<CommonAPI::Deployable<InArgs_, DeplIn_Args>...> in_;
+};
+
+class DBusErrorEventHelper {
+public:
+ template <int... ErrorEventsIndices_, class... ErrorEvents_>
+ static void notifyListeners(const DBusMessage &_reply,
+ const std::string &_errorName,
+ index_sequence<ErrorEventsIndices_...>,
+ const std::tuple<ErrorEvents_*...> &_errorEvents) {
+
+ notifyListeners(_reply, _errorName, std::get<ErrorEventsIndices_>(_errorEvents)...);
+ }
+
+ template <class ErrorEvent_>
+ static void notifyListeners(const DBusMessage &_reply,
+ const std::string &_errorName,
+ ErrorEvent_ *_errorEvent) {
+ if(_errorEvent->getErrorName() == _errorName)
+ _errorEvent->notifyErrorEventListeners(_reply);
+
+ }
+
+ template <class ErrorEvent_, class... Rest_>
+ static void notifyListeners(const DBusMessage &_reply,
+ const std::string &_errorName,
+ ErrorEvent_ *_errorEvent,
+ Rest_&... _rest) {
+ if(_errorEvent->getErrorName() == _errorName)
+ _errorEvent->notifyErrorEventListeners(_reply);
+ notifyListeners(_reply, _errorName, _rest...);
+ }
+};
+
+} // namespace DBus
+} // namespace CommonAPI
+
+#endif /* COMMONAPI_DBUS_DBUSERROREVENT_HPP_ */
diff --git a/include/CommonAPI/DBus/DBusEvent.hpp b/include/CommonAPI/DBus/DBusEvent.hpp
index 2637acf..945988d 100644
--- a/include/CommonAPI/DBus/DBusEvent.hpp
+++ b/include/CommonAPI/DBus/DBusEvent.hpp
@@ -22,7 +22,7 @@ namespace CommonAPI {
namespace DBus {
template <typename Event_, typename... Arguments_>
-class DBusEvent: public Event_, public DBusProxyConnection::DBusSignalHandler {
+class DBusEvent: public Event_ {
public:
typedef typename Event_::Subscription Subscription;
typedef typename Event_::Listener Listener;
@@ -31,6 +31,7 @@ public:
const std::string &_name, const std::string &_signature,
std::tuple<Arguments_...> _arguments)
: proxy_(_proxy),
+ signalHandler_(std::make_shared<SignalHandler>(_proxy, this)),
name_(_name), signature_(_signature),
getMethodName_(""),
arguments_(_arguments) {
@@ -44,6 +45,7 @@ public:
const std::string &_path, const std::string &_interface,
std::tuple<Arguments_...> _arguments)
: proxy_(_proxy),
+ signalHandler_(std::make_shared<SignalHandler>(_proxy, this)),
name_(_name), signature_(_signature),
path_(_path), interface_(_interface),
getMethodName_(""),
@@ -56,6 +58,7 @@ public:
const std::string &_getMethodName,
std::tuple<Arguments_...> _arguments)
: proxy_(_proxy),
+ signalHandler_(std::make_shared<SignalHandler>(_proxy, this)),
name_(_name),
signature_(_signature),
getMethodName_(_getMethodName),
@@ -66,37 +69,71 @@ public:
}
virtual ~DBusEvent() {
- proxy_.removeSignalMemberHandler(subscription_, this);
+ proxy_.removeSignalMemberHandler(subscription_, signalHandler_.get());
}
- virtual void onSignalDBusMessage(const DBusMessage &_message) {
- handleSignalDBusMessage(_message, typename make_sequence<sizeof...(Arguments_)>::type());
+ virtual void onError(const CommonAPI::CallStatus status) {
+ (void)status;
}
- virtual void onInitialValueSignalDBusMessage(const DBusMessage&_message, const uint32_t tag) {
- handleSignalDBusMessage(tag, _message, typename make_sequence<sizeof...(Arguments_)>::type());
+ virtual void onSpecificError(const CommonAPI::CallStatus status, const uint32_t tag) {
+ (void)status;
+ (void)tag;
}
- virtual void onError(const CommonAPI::CallStatus status) {
- (void) status;
+ virtual void setSubscriptionToken(const DBusProxyConnection::DBusSignalHandlerToken token, const uint32_t tag) {
+ (void)token;
+ (void)tag;
}
protected:
+
+ class SignalHandler : public DBusProxyConnection::DBusSignalHandler,
+ public std::enable_shared_from_this<SignalHandler> {
+ public:
+ SignalHandler(DBusProxyBase&_proxy,
+ DBusEvent<Event_, Arguments_ ...>* _dbusEvent) :
+ proxy_(_proxy),
+ dbusEvent_(_dbusEvent) {
+
+ }
+
+ virtual void onSignalDBusMessage(const DBusMessage &_message) {
+ dbusEvent_->handleSignalDBusMessage(_message, typename make_sequence<sizeof...(Arguments_)>::type());
+ }
+
+ virtual void onInitialValueSignalDBusMessage(const DBusMessage&_message, const uint32_t tag) {
+ dbusEvent_->handleSignalDBusMessage(tag, _message, typename make_sequence<sizeof...(Arguments_)>::type());
+ }
+
+ virtual void onSpecificError(const CommonAPI::CallStatus status, const uint32_t tag) {
+ dbusEvent_->onSpecificError(status, tag);
+ }
+
+ virtual void setSubscriptionToken(const DBusProxyConnection::DBusSignalHandlerToken token, const uint32_t tag) {
+ dbusEvent_->setSubscriptionToken(token, tag);
+ }
+
+ private :
+ DBusProxyBase& proxy_;
+ DBusEvent<Event_, Arguments_ ...>* dbusEvent_;
+ };
+
virtual void onFirstListenerAdded(const Listener &_listener) {
(void)_listener;
subscription_ = proxy_.addSignalMemberHandler(
- path_, interface_, name_, signature_, getMethodName_, this, false);
+ path_, interface_, name_, signature_, getMethodName_, signalHandler_, false);
}
virtual void onListenerAdded(const Listener &_listener, const Subscription subscription) {
(void)_listener;
if ("" != getMethodName_) {
- proxy_.getCurrentValueForSignalListener(getMethodName_, this, subscription);
+ proxy_.getCurrentValueForSignalListener(getMethodName_, signalHandler_, subscription);
}
}
virtual void onLastListenerRemoved(const Listener&) {
- proxy_.removeSignalMemberHandler(subscription_, this);
+ proxy_.removeSignalMemberHandler(subscription_, signalHandler_.get());
std::get<0>(subscription_) = "";
std::get<1>(subscription_) = "";
std::get<2>(subscription_) = "";
@@ -124,6 +161,7 @@ public:
}
DBusProxyBase &proxy_;
+ std::shared_ptr<SignalHandler> signalHandler_;
std::string name_;
std::string signature_;
diff --git a/include/CommonAPI/DBus/DBusFreedesktopAttribute.hpp b/include/CommonAPI/DBus/DBusFreedesktopAttribute.hpp
index 4f78f5c..8f35928 100644
--- a/include/CommonAPI/DBus/DBusFreedesktopAttribute.hpp
+++ b/include/CommonAPI/DBus/DBusFreedesktopAttribute.hpp
@@ -151,8 +151,7 @@ class DBusFreedesktopAttribute
template<class, class, class>
class LegacyEvent;
template <template <class...> class Type_, class Types_, class DataType_, class DataDeplType_>
-class LegacyEvent<Type_<Types_>, DataType_, DataDeplType_>: public Type_<Types_>,
- public DBusProxyConnection::DBusSignalHandler {
+class LegacyEvent<Type_<Types_>, DataType_, DataDeplType_>: public Type_<Types_> {
public:
typedef Types_ ValueType;
typedef typename Type_<ValueType>::Listener Listener;
@@ -170,6 +169,7 @@ public:
mapDepl_(nullptr, &variantDepl_),
deployedMap_(&mapDepl_),
proxy_(_proxy),
+ signalHandler_(std::make_shared<SignalHandler>(_proxy, this, &variantDepl_)),
isSubcriptionSet_(false),
internalEvent_(_proxy,
"PropertiesChanged",
@@ -179,7 +179,47 @@ public:
std::make_tuple("", deployedMap_, InvalidArray())) {
}
+ virtual ~LegacyEvent() {}
+
protected:
+
+ class SignalHandler : public DBusProxyConnection::DBusSignalHandler,
+ public std::enable_shared_from_this<SignalHandler> {
+ public:
+ SignalHandler(DBusProxy& _proxy,
+ LegacyEvent<Type_<Types_>, DataType_, DataDeplType_>* _legacyEvent,
+ VariantDeployment<DataDeplType_>* _variantDepl) :
+ proxy_(_proxy),
+ legacyEvent_(_legacyEvent),
+ variantDepl_(_variantDepl) {
+
+ }
+
+ virtual void onInitialValueSignalDBusMessage(const DBusMessage&_message, const uint32_t tag) {
+ CommonAPI::Deployable<Variant<DataType_>, VariantDeployment<DataDeplType_>> deployedValue(variantDepl_);
+ DBusInputStream input(_message);
+ if (DBusSerializableArguments<
+ CommonAPI::Deployable<
+ Variant<DataType_>,
+ VariantDeployment<DataDeplType_>
+ >
+ >::deserialize(input, deployedValue)) {
+ Variant<DataType_> v = deployedValue.getValue();
+ const DataType_ &value = v.template get<DataType_>();
+ legacyEvent_->notifySpecificListener(tag, value);
+ }
+ }
+
+ virtual void onSignalDBusMessage(const DBusMessage&) {
+ // ignore
+ }
+
+ private:
+ DBusProxy& proxy_;
+ LegacyEvent<Type_<Types_>, DataType_, DataDeplType_>* legacyEvent_;
+ VariantDeployment<DataDeplType_>* variantDepl_;
+ };
+
void onFirstListenerAdded(const Listener &) {
if (!isSubcriptionSet_) {
subscription_ = internalEvent_.subscribe(
@@ -202,26 +242,9 @@ protected:
virtual void onListenerAdded(const Listener& listener, const Subscription subscription) {
(void)listener;
- proxy_.freeDesktopGetCurrentValueForSignalListener(this, subscription, interfaceName_, propertyName_);
+ proxy_.freeDesktopGetCurrentValueForSignalListener(signalHandler_, subscription, interfaceName_, propertyName_);
}
- virtual void onInitialValueSignalDBusMessage(const DBusMessage&_message, const uint32_t tag) {
- CommonAPI::Deployable<Variant<DataType_>, VariantDeployment<DataDeplType_>> deployedValue(&variantDepl_);
- DBusInputStream input(_message);
- if (DBusSerializableArguments<
- CommonAPI::Deployable<
- Variant<DataType_>,
- VariantDeployment<DataDeplType_>
- >
- >::deserialize(input, deployedValue)) {
- Variant<DataType_> v = deployedValue.getValue();
- const DataType_ &value = v.template get<DataType_>();
- this->notifySpecificListener(tag, value);
- }
- }
- virtual void onSignalDBusMessage(const DBusMessage&) {
- // ignore
- }
void onLastListenerRemoved(const Listener &) {
if (isSubcriptionSet_) {
internalEvent_.unsubscribe(subscription_);
@@ -235,6 +258,7 @@ protected:
PropertyMapDeployment mapDepl_;
DeployedPropertyMap deployedMap_;
DBusProxy &proxy_;
+ std::shared_ptr<SignalHandler> signalHandler_;
typename DBusEvent<SignalEvent, std::string, DeployedPropertyMap, InvalidArray>::Subscription subscription_;
bool isSubcriptionSet_;
diff --git a/include/CommonAPI/DBus/DBusInstanceAvailabilityStatusChangedEvent.hpp b/include/CommonAPI/DBus/DBusInstanceAvailabilityStatusChangedEvent.hpp
index 1f5bcc2..9be2e9a 100644
--- a/include/CommonAPI/DBus/DBusInstanceAvailabilityStatusChangedEvent.hpp
+++ b/include/CommonAPI/DBus/DBusInstanceAvailabilityStatusChangedEvent.hpp
@@ -26,8 +26,7 @@ namespace DBus {
// TODO Check to move logic to DBusServiceRegistry, now every proxy will deserialize the messages!
class DBusInstanceAvailabilityStatusChangedEvent:
- public ProxyManager::InstanceAvailabilityStatusChangedEvent,
- public DBusProxyConnection::DBusSignalHandler {
+ public ProxyManager::InstanceAvailabilityStatusChangedEvent {
public:
typedef std::function<void(const CallStatus &, const std::vector<DBusAddress> &)> GetAvailableServiceInstancesCallback;
@@ -38,8 +37,6 @@ class DBusInstanceAvailabilityStatusChangedEvent:
COMMONAPI_EXPORT virtual ~DBusInstanceAvailabilityStatusChangedEvent();
- COMMONAPI_EXPORT virtual void onSignalDBusMessage(const DBusMessage& dbusMessage);
-
COMMONAPI_EXPORT void getAvailableServiceInstances(CommonAPI::CallStatus &_status, std::vector<DBusAddress> &_availableServiceInstances);
COMMONAPI_EXPORT std::future<CallStatus> getAvailableServiceInstancesAsync(GetAvailableServiceInstancesCallback _callback);
@@ -50,6 +47,15 @@ class DBusInstanceAvailabilityStatusChangedEvent:
ProxyManager::GetInstanceAvailabilityStatusCallback _callback);
protected:
+
+ class SignalHandler : public DBusProxyConnection::DBusSignalHandler {
+ public:
+ COMMONAPI_EXPORT SignalHandler(DBusInstanceAvailabilityStatusChangedEvent* _instanceAvblStatusEvent);
+ COMMONAPI_EXPORT virtual void onSignalDBusMessage(const DBusMessage& dbusMessage);
+ private:
+ DBusInstanceAvailabilityStatusChangedEvent* instanceAvblStatusEvent_;
+ };
+
virtual void onFirstListenerAdded(const Listener&);
virtual void onLastListenerRemoved(const Listener&);
@@ -76,7 +82,9 @@ class DBusInstanceAvailabilityStatusChangedEvent:
void translate(const DBusObjectManagerStub::DBusObjectPathAndInterfacesDict &_dict,
std::vector<DBusAddress> &_serviceInstances);
+ std::shared_ptr<SignalHandler> signalHandler_;
DBusProxy &proxy_;
+ std::weak_ptr<DBusProxy> proxyWeakPtr_;
std::string observedDbusInterfaceName_;
std::string observedCapiInterfaceName_;
DBusProxyConnection::DBusSignalHandlerToken interfacesAddedSubscription_;
diff --git a/include/CommonAPI/DBus/DBusMainLoopContext.hpp b/include/CommonAPI/DBus/DBusMainLoopContext.hpp
index 6de84f8..708cfa3 100644
--- a/include/CommonAPI/DBus/DBusMainLoopContext.hpp
+++ b/include/CommonAPI/DBus/DBusMainLoopContext.hpp
@@ -124,6 +124,7 @@ private:
int pipeFileDescriptors_[2];
pollfd pollFileDescriptor_;
+
std::vector<CommonAPI::DispatchSource*> dependentDispatchSources_;
std::queue<std::shared_ptr<QueueEntry>> queue_;
@@ -134,7 +135,6 @@ private:
const int pipeValue_;
#ifdef WIN32
HANDLE wsaEvent_;
- OVERLAPPED ov;
#endif
};
diff --git a/include/CommonAPI/DBus/DBusMessage.hpp b/include/CommonAPI/DBus/DBusMessage.hpp
index b005904..ece0b21 100644
--- a/include/CommonAPI/DBus/DBusMessage.hpp
+++ b/include/CommonAPI/DBus/DBusMessage.hpp
@@ -56,7 +56,7 @@ public:
DBusMessage createMethodReturn(const std::string &_signature) const;
- DBusMessage createMethodError(const std::string &_name, const std::string &_reason = "") const;
+ DBusMessage createMethodError(const std::string &_name, const std::string &_signature = "s", const std::string &_reason = "") const;
static DBusMessage createSignal(const std::string& objectPath,
const std::string& interfaceName,
diff --git a/include/CommonAPI/DBus/DBusProxy.hpp b/include/CommonAPI/DBus/DBusProxy.hpp
index 072e356..cc9bd06 100644
--- a/include/CommonAPI/DBus/DBusProxy.hpp
+++ b/include/CommonAPI/DBus/DBusProxy.hpp
@@ -64,12 +64,12 @@ public:
const std::string& interfaceName,
const std::string& interfaceMemberName,
const std::string& interfaceMemberSignature,
- DBusProxyConnection::DBusSignalHandler* dbusSignalHandler,
+ std::weak_ptr<DBusProxyConnection::DBusSignalHandler> dbusSignalHandler,
uint32_t tag);
COMMONAPI_EXPORT void insertSelectiveSubscription(
const std::string& interfaceMemberName,
- DBusProxyConnection::DBusSignalHandler* dbusSignalHandler,
+ std::weak_ptr<DBusProxyConnection::DBusSignalHandler> dbusSignalHandler,
uint32_t tag, std::string interfaceMemberSignature);
COMMONAPI_EXPORT void unsubscribeFromSelectiveBroadcast(const std::string& eventName,
DBusProxyConnection::DBusSignalHandlerToken subscription,
@@ -82,7 +82,7 @@ public:
const std::string &interfaceName,
const std::string &signalName,
const std::string &signalSignature,
- DBusProxyConnection::DBusSignalHandler *dbusSignalHandler,
+ std::weak_ptr<DBusProxyConnection::DBusSignalHandler> dbusSignalHandler,
const bool justAddFilter);
COMMONAPI_EXPORT virtual DBusProxyConnection::DBusSignalHandlerToken addSignalMemberHandler(
@@ -91,25 +91,25 @@ public:
const std::string &signalName,
const std::string &signalSignature,
const std::string &getMethodName,
- DBusProxyConnection::DBusSignalHandler *dbusSignalHandler,
+ std::weak_ptr<DBusProxyConnection::DBusSignalHandler> dbusSignalHandler,
const bool justAddFilter);
COMMONAPI_EXPORT virtual bool removeSignalMemberHandler(
const DBusProxyConnection::DBusSignalHandlerToken &_dbusSignalHandlerToken,
- const DBusProxyConnection::DBusSignalHandler *_dbusSignalHandler = NULL);
+ const DBusProxyConnection::DBusSignalHandler* _dbusSignalHandler = NULL);
COMMONAPI_EXPORT virtual void getCurrentValueForSignalListener(
const std::string &getMethodName,
- DBusProxyConnection::DBusSignalHandler *dbusSignalHandler,
+ std::weak_ptr<DBusProxyConnection::DBusSignalHandler> dbusSignalHandler,
const uint32_t subscription);
COMMONAPI_EXPORT virtual void freeDesktopGetCurrentValueForSignalListener(
- DBusProxyConnection::DBusSignalHandler *dbusSignalHandler,
+ std::weak_ptr<DBusProxyConnection::DBusSignalHandler> dbusSignalHandler,
const uint32_t subscription,
const std::string &interfaceName,
const std::string &propertyName);
- COMMONAPI_EXPORT virtual void notifySpecificListener(std::weak_ptr<DBusProxy> _dbusProxy,
+ COMMONAPI_EXPORT static void notifySpecificListener(std::weak_ptr<DBusProxy> _dbusProxy,
const ProxyStatusEvent::Listener &_listener,
const ProxyStatusEvent::Subscription _subscription);
@@ -120,21 +120,22 @@ private:
const std::string,
const std::string,
const std::string,
- DBusProxyConnection::DBusSignalHandler*,
+ std::weak_ptr<DBusProxyConnection::DBusSignalHandler>,
const bool,
bool
> SignalMemberHandlerTuple;
COMMONAPI_EXPORT DBusProxy(const DBusProxy &) = delete;
- COMMONAPI_EXPORT void onDBusServiceInstanceStatus(const AvailabilityStatus& availabilityStatus);
+ COMMONAPI_EXPORT void onDBusServiceInstanceStatus(std::shared_ptr<DBusProxy> _proxy,
+ const AvailabilityStatus& availabilityStatus);
COMMONAPI_EXPORT void signalMemberCallback(const CallStatus dbusMessageCallStatus,
const DBusMessage& dbusMessage,
- DBusProxyConnection::DBusSignalHandler* dbusSignalHandlers,
+ std::weak_ptr<DBusProxyConnection::DBusSignalHandler> dbusSignalHandlers,
const uint32_t tag);
COMMONAPI_EXPORT void signalInitialValueCallback(const CallStatus dbusMessageCallStatus,
const DBusMessage& dbusMessage,
- DBusProxyConnection::DBusSignalHandler* dbusSignalHandlers,
+ std::weak_ptr<DBusProxyConnection::DBusSignalHandler> dbusSignalHandlers,
const uint32_t tag);
COMMONAPI_EXPORT void addSignalMemberHandlerToQueue(SignalMemberHandlerTuple& _signalMemberHandler);
@@ -155,7 +156,7 @@ private:
mutable std::mutex signalMemberHandlerQueueMutex_;
std::map<std::string,
- std::tuple<DBusProxyConnection::DBusSignalHandler*, uint32_t,
+ std::tuple<std::weak_ptr<DBusProxyConnection::DBusSignalHandler>, uint32_t,
std::string>> selectiveBroadcastHandlers;
mutable std::mutex selectiveBroadcastHandlersMutex_;
@@ -170,8 +171,6 @@ private:
std::promise<AvailabilityStatus>
> AvailabilityTimeout_t;
mutable std::list<AvailabilityTimeout_t> timeouts_;
-
- std::weak_ptr<DBusProxy> selfReference_;
};
diff --git a/include/CommonAPI/DBus/DBusProxyAsyncCallbackHandler.hpp b/include/CommonAPI/DBus/DBusProxyAsyncCallbackHandler.hpp
index 1a00adc..d21807d 100644
--- a/include/CommonAPI/DBus/DBusProxyAsyncCallbackHandler.hpp
+++ b/include/CommonAPI/DBus/DBusProxyAsyncCallbackHandler.hpp
@@ -18,36 +18,40 @@
#include <CommonAPI/DBus/DBusMessage.hpp>
#include <CommonAPI/DBus/DBusProxyConnection.hpp>
#include <CommonAPI/DBus/DBusSerializableArguments.hpp>
+#include <CommonAPI/DBus/DBusErrorEvent.hpp>
namespace CommonAPI {
namespace DBus {
-template<typename DelegateObjectType_, typename ... ArgTypes_>
-class DBusProxyAsyncCallbackHandler:
+template <class, class...>
+class DBusProxyAsyncCallbackHandler;
+
+template <class DelegateObjectType_, class ... ArgTypes_>
+class DBusProxyAsyncCallbackHandler :
public DBusProxyConnection::DBusMessageReplyAsyncHandler {
public:
struct Delegate {
typedef std::function<void(CallStatus, ArgTypes_...)> FunctionType;
- Delegate(std::shared_ptr<DelegateObjectType_> object, FunctionType function) :
- function_(std::move(function)) {
- object_ = object;
+ Delegate(std::shared_ptr<DelegateObjectType_> _object, FunctionType _function) :
+ function_(std::move(_function)) {
+ object_ = _object;
}
std::weak_ptr<DelegateObjectType_> object_;
FunctionType function_;
};
static std::unique_ptr<DBusProxyConnection::DBusMessageReplyAsyncHandler> create(
- Delegate& delegate, std::tuple<ArgTypes_...> args) {
+ Delegate& _delegate, const std::tuple<ArgTypes_...>& _args) {
return std::unique_ptr<DBusProxyConnection::DBusMessageReplyAsyncHandler>(
- new DBusProxyAsyncCallbackHandler<DelegateObjectType_, ArgTypes_...>(std::move(delegate), args));
+ new DBusProxyAsyncCallbackHandler<DelegateObjectType_, ArgTypes_...>(std::move(_delegate), _args));
}
DBusProxyAsyncCallbackHandler() = delete;
- DBusProxyAsyncCallbackHandler(Delegate&& delegate, std::tuple<ArgTypes_...> args)
- : delegate_(std::move(delegate)),
- args_(args),
+ DBusProxyAsyncCallbackHandler(Delegate&& _delegate, const std::tuple<ArgTypes_...>& _args)
+ : delegate_(std::move(_delegate)),
+ args_(_args),
executionStarted_(false),
executionFinished_(false),
timeoutOccurred_(false),
@@ -62,10 +66,10 @@ class DBusProxyAsyncCallbackHandler:
return promise_.get_future();
}
- virtual void onDBusMessageReply(const CallStatus& dbusMessageCallStatus,
- const DBusMessage& dbusMessage) {
- promise_.set_value(handleDBusMessageReply(dbusMessageCallStatus,
- dbusMessage,
+ virtual void onDBusMessageReply(const CallStatus& _dbusMessageCallStatus,
+ const DBusMessage& _dbusMessage) {
+ promise_.set_value(handleDBusMessageReply(_dbusMessageCallStatus,
+ _dbusMessage,
typename make_sequence<sizeof...(ArgTypes_)>::type(), args_));
}
@@ -109,42 +113,39 @@ class DBusProxyAsyncCallbackHandler:
asyncHandlerMutex_.unlock();
}
+ protected:
+ Delegate delegate_;
+ std::promise<CallStatus> promise_;
+ std::tuple<ArgTypes_...> args_;
+
private:
template <int... ArgIndices_>
inline CallStatus handleDBusMessageReply(
- const CallStatus dbusMessageCallStatus,
- const DBusMessage& dbusMessage,
+ const CallStatus _dbusMessageCallStatus,
+ const DBusMessage& _dbusMessage,
index_sequence<ArgIndices_...>,
- std::tuple<ArgTypes_...> argTuple) const {
- (void)argTuple; // this suppresses warning "set but not used" in case of empty _ArgTypes
+ std::tuple<ArgTypes_...>& _argTuple) const {
+ (void)_argTuple; // this suppresses warning "set but not used" in case of empty _ArgTypes
// Looks like: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=57560 - Bug 57650
- CallStatus callStatus = dbusMessageCallStatus;
-
- if (dbusMessageCallStatus == CallStatus::SUCCESS) {
- if (!dbusMessage.isErrorType()) {
- DBusInputStream dbusInputStream(dbusMessage);
- const bool success
- = DBusSerializableArguments<ArgTypes_...>::deserialize(
- dbusInputStream,
- std::get<ArgIndices_>(argTuple)...);
- if (!success)
- callStatus = CallStatus::REMOTE_ERROR;
+ CallStatus callStatus = _dbusMessageCallStatus;
+
+ if (_dbusMessageCallStatus == CallStatus::SUCCESS) {
+ DBusInputStream dbusInputStream(_dbusMessage);
+ if(DBusSerializableArguments<ArgTypes_...>::deserialize(dbusInputStream,
+ std::get<ArgIndices_>(_argTuple)...)) {
} else {
callStatus = CallStatus::REMOTE_ERROR;
}
}
- //check if object is expired
- if(!delegate_.object_.expired())
- delegate_.function_(callStatus, std::move(std::get<ArgIndices_>(argTuple))...);
+ //ensure that delegate object (e.g. Proxy) survives
+ if(auto itsDelegateObject = delegate_.object_.lock())
+ delegate_.function_(callStatus, std::move(std::get<ArgIndices_>(_argTuple))...);
return callStatus;
}
- std::promise<CallStatus> promise_;
- Delegate delegate_;
- std::tuple<ArgTypes_...> args_;
bool executionStarted_;
bool executionFinished_;
bool timeoutOccurred_;
@@ -153,6 +154,87 @@ class DBusProxyAsyncCallbackHandler:
std::mutex asyncHandlerMutex_;
};
+template<
+ template <class...> class ErrorEventsTuple_, class... ErrorEvents_,
+ class DelegateObjectType_, class... ArgTypes_>
+class DBusProxyAsyncCallbackHandler<
+ ErrorEventsTuple_<ErrorEvents_...>,
+ DelegateObjectType_,
+ ArgTypes_...>:
+ public DBusProxyAsyncCallbackHandler<DelegateObjectType_, ArgTypes_...> {
+
+public:
+
+ static std::unique_ptr<DBusProxyConnection::DBusMessageReplyAsyncHandler> create(
+ typename DBusProxyAsyncCallbackHandler<DelegateObjectType_, ArgTypes_...>::Delegate& _delegate,
+ const std::tuple<ArgTypes_...>& _args,
+ const ErrorEventsTuple_<ErrorEvents_...> &_errorEvents) {
+ return std::unique_ptr<DBusProxyConnection::DBusMessageReplyAsyncHandler>(
+ new DBusProxyAsyncCallbackHandler<ErrorEventsTuple_<ErrorEvents_...>, DelegateObjectType_, ArgTypes_...>(std::move(_delegate), _args, _errorEvents));
+ }
+
+ DBusProxyAsyncCallbackHandler() = delete;
+ DBusProxyAsyncCallbackHandler(typename DBusProxyAsyncCallbackHandler<DelegateObjectType_, ArgTypes_...>::Delegate&& _delegate,
+ const std::tuple<ArgTypes_...>& _args,
+ const ErrorEventsTuple_<ErrorEvents_...> &_errorEvents) :
+ DBusProxyAsyncCallbackHandler<DelegateObjectType_, ArgTypes_...>(std::move(_delegate), _args),
+ errorEvents_(_errorEvents) {}
+
+ virtual ~DBusProxyAsyncCallbackHandler() {
+ // free assigned std::function<> immediately
+ this->delegate_.function_ = [](CallStatus, ArgTypes_...) {};
+ }
+
+ virtual void onDBusMessageReply(const CallStatus& _dbusMessageCallStatus,
+ const DBusMessage& _dbusMessage) {
+ this->promise_.set_value(handleDBusMessageReply(
+ _dbusMessageCallStatus,
+ _dbusMessage,
+ typename make_sequence<sizeof...(ArgTypes_)>::type(), this->args_));
+ }
+
+private:
+
+ template <int... ArgIndices_>
+ inline CallStatus handleDBusMessageReply(
+ const CallStatus _dbusMessageCallStatus,
+ const DBusMessage& _dbusMessage,
+ index_sequence<ArgIndices_...>,
+ std::tuple<ArgTypes_...>& _argTuple) const {
+ (void)_argTuple; // this suppresses warning "set but not used" in case of empty _ArgTypes
+ // Looks like: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=57560 - Bug 57650
+
+ CallStatus callStatus = _dbusMessageCallStatus;
+
+ if (_dbusMessageCallStatus == CallStatus::SUCCESS) {
+ DBusInputStream dbusInputStream(_dbusMessage);
+ if(DBusSerializableArguments<ArgTypes_...>::deserialize(dbusInputStream,
+ std::get<ArgIndices_>(_argTuple)...)) {
+ } else {
+ callStatus = CallStatus::REMOTE_ERROR;
+ }
+ } else {
+ if(_dbusMessage.isErrorType()) {
+ //ensure that delegate object (e.g. Proxy and its error events) survives
+ if(auto itsDelegateObject = this->delegate_.object_.lock()) {
+ DBusErrorEventHelper::notifyListeners(_dbusMessage,
+ _dbusMessage.getError(),
+ typename make_sequence_range<sizeof...(ErrorEvents_), 0>::type(),
+ errorEvents_);
+ }
+ }
+ }
+
+ //ensure that delegate object (e.g. Proxy) survives
+ if(auto itsDelegateObject = this->delegate_.object_.lock())
+ this->delegate_.function_(callStatus, std::move(std::get<ArgIndices_>(_argTuple))...);
+
+ return callStatus;
+ }
+
+ ErrorEventsTuple_<ErrorEvents_...> errorEvents_;
+};
+
} // namespace DBus
} // namespace CommonAPI
diff --git a/include/CommonAPI/DBus/DBusProxyAsyncSignalMemberCallbackHandler.hpp b/include/CommonAPI/DBus/DBusProxyAsyncSignalMemberCallbackHandler.hpp
index 11cb354..788c1ff 100644
--- a/include/CommonAPI/DBus/DBusProxyAsyncSignalMemberCallbackHandler.hpp
+++ b/include/CommonAPI/DBus/DBusProxyAsyncSignalMemberCallbackHandler.hpp
@@ -26,7 +26,7 @@ class DBusProxyAsyncSignalMemberCallbackHandler: public DBusProxyConnection::DBu
public:
struct Delegate {
- typedef std::function<void(CallStatus, DBusMessage, DBusProxyConnection::DBusSignalHandler*, uint32_t)> FunctionType;
+ typedef std::function<void(CallStatus, DBusMessage, std::weak_ptr<DBusProxyConnection::DBusSignalHandler>, uint32_t)> FunctionType;
Delegate(std::shared_ptr<DelegateObjectType_> object, FunctionType function) :
function_(std::move(function)) {
@@ -37,7 +37,7 @@ class DBusProxyAsyncSignalMemberCallbackHandler: public DBusProxyConnection::DBu
};
static std::unique_ptr<DBusProxyConnection::DBusMessageReplyAsyncHandler> create(
- Delegate& delegate, DBusProxyConnection::DBusSignalHandler* dbusSignalHandler,
+ Delegate& delegate, std::weak_ptr<DBusProxyConnection::DBusSignalHandler> dbusSignalHandler,
const uint32_t tag) {
return std::unique_ptr<DBusProxyConnection::DBusMessageReplyAsyncHandler>(
new DBusProxyAsyncSignalMemberCallbackHandler<DelegateObjectType_>(std::move(delegate), dbusSignalHandler, tag));
@@ -45,8 +45,8 @@ class DBusProxyAsyncSignalMemberCallbackHandler: public DBusProxyConnection::DBu
DBusProxyAsyncSignalMemberCallbackHandler() = delete;
DBusProxyAsyncSignalMemberCallbackHandler(Delegate&& delegate,
- DBusProxyConnection::DBusSignalHandler* dbusSignalHandler,
- const uint32_t tag):
+ std::weak_ptr<DBusProxyConnection::DBusSignalHandler> dbusSignalHandler,
+ const uint32_t tag):
delegate_(std::move(delegate)), dbusSignalHandler_(dbusSignalHandler), tag_(tag),
executionStarted_(false), executionFinished_(false),
timeoutOccurred_(false), hasToBeDeleted_(false) {
@@ -114,7 +114,7 @@ class DBusProxyAsyncSignalMemberCallbackHandler: public DBusProxyConnection::DBu
std::promise<CallStatus> promise_;
const Delegate delegate_;
- DBusProxyConnection::DBusSignalHandler* dbusSignalHandler_;
+ std::weak_ptr<DBusProxyConnection::DBusSignalHandler> dbusSignalHandler_;
const uint32_t tag_;
bool executionStarted_;
bool executionFinished_;
diff --git a/include/CommonAPI/DBus/DBusProxyBase.hpp b/include/CommonAPI/DBus/DBusProxyBase.hpp
index 2193ca7..e0fbaec 100644
--- a/include/CommonAPI/DBus/DBusProxyBase.hpp
+++ b/include/CommonAPI/DBus/DBusProxyBase.hpp
@@ -49,7 +49,7 @@ public:
const std::string &interfaceName,
const std::string &signalName,
const std::string &signalSignature,
- DBusProxyConnection::DBusSignalHandler *dbusSignalHandler,
+ std::weak_ptr<DBusProxyConnection::DBusSignalHandler> dbusSignalHandler,
const bool justAddFilter);
COMMONAPI_EXPORT virtual DBusProxyConnection::DBusSignalHandlerToken addSignalMemberHandler(
@@ -58,16 +58,16 @@ public:
const std::string &signalName,
const std::string &signalSignature,
const std::string &getMethodName,
- DBusProxyConnection::DBusSignalHandler *dbusSignalHandler,
+ std::weak_ptr<DBusProxyConnection::DBusSignalHandler> dbusSignalHandler,
const bool justAddFilter);
COMMONAPI_EXPORT virtual bool removeSignalMemberHandler(
const DBusProxyConnection::DBusSignalHandlerToken &_dbusSignalHandlerToken,
- const DBusProxyConnection::DBusSignalHandler *_dbusSignalHandler = NULL);
+ const DBusProxyConnection::DBusSignalHandler* dbusSignalHandler = NULL);
COMMONAPI_EXPORT virtual void getCurrentValueForSignalListener(
const std::string &_getMethodName,
- DBusProxyConnection::DBusSignalHandler *_handler,
+ std::weak_ptr<DBusProxyConnection::DBusSignalHandler> _handler,
const uint32_t _subscription) {
(void)_getMethodName;
(void)_handler;
diff --git a/include/CommonAPI/DBus/DBusProxyConnection.hpp b/include/CommonAPI/DBus/DBusProxyConnection.hpp
index 6065a8b..d0db2ba 100644
--- a/include/CommonAPI/DBus/DBusProxyConnection.hpp
+++ b/include/CommonAPI/DBus/DBusProxyConnection.hpp
@@ -61,7 +61,10 @@ class DBusProxyConnection {
// objectPath, interfaceName, interfaceMemberName, interfaceMemberSignature
typedef std::tuple<std::string, std::string, std::string, std::string> DBusSignalHandlerPath;
- typedef std::unordered_map<DBusSignalHandlerPath, std::pair<std::shared_ptr<std::recursive_mutex>, std::set<DBusSignalHandler* >>> DBusSignalHandlerTable;
+ typedef std::unordered_map<DBusSignalHandlerPath,
+ std::pair<std::shared_ptr<std::recursive_mutex>,
+ std::map<DBusSignalHandler*,
+ std::weak_ptr<DBusProxyConnection::DBusSignalHandler>>>> DBusSignalHandlerTable;
typedef DBusSignalHandlerPath DBusSignalHandlerToken;
class DBusSignalHandler {
@@ -98,14 +101,14 @@ class DBusProxyConnection {
const std::string& interfaceName,
const std::string& interfaceMemberName,
const std::string& interfaceMemberSignature,
- DBusSignalHandler* dbusSignalHandler,
+ std::weak_ptr<DBusSignalHandler> dbusSignalHandler,
const bool justAddFilter = false) = 0;
virtual void subscribeForSelectiveBroadcast(const std::string& objectPath,
const std::string& interfaceName,
const std::string& interfaceMemberName,
const std::string& interfaceMemberSignature,
- DBusSignalHandler* dbusSignalHandler,
+ std::weak_ptr<DBusSignalHandler> dbusSignalHandler,
DBusProxy* callingProxy,
uint32_t tag) = 0;
@@ -118,7 +121,7 @@ class DBusProxyConnection {
const DBusSignalHandler* dbusSignalHandler = NULL) = 0;
virtual bool addObjectManagerSignalMemberHandler(const std::string& dbusBusName,
- DBusSignalHandler* dbusSignalHandler) = 0;
+ std::weak_ptr<DBusSignalHandler> dbusSignalHandler) = 0;
virtual bool removeObjectManagerSignalMemberHandler(const std::string& dbusBusName,
DBusSignalHandler* dbusSignalHandler) = 0;
@@ -139,7 +142,7 @@ class DBusProxyConnection {
virtual void sendPendingSelectiveSubscription(
DBusProxy* proxy, std::string interfaceMemberName,
- DBusSignalHandler* dbusSignalHandler, uint32_t tag,
+ std::weak_ptr<DBusSignalHandler> dbusSignalHandler, uint32_t tag,
std::string interfaceMemberSignature) = 0;
virtual void pushDBusMessageReplyToMainLoop(const DBusMessage& reply,
diff --git a/include/CommonAPI/DBus/DBusProxyHelper.hpp b/include/CommonAPI/DBus/DBusProxyHelper.hpp
index 8bd0154..3f9e175 100644
--- a/include/CommonAPI/DBus/DBusProxyHelper.hpp
+++ b/include/CommonAPI/DBus/DBusProxyHelper.hpp
@@ -21,13 +21,14 @@
#include <CommonAPI/DBus/DBusSerializableArguments.hpp>
#include <CommonAPI/DBus/DBusProxyAsyncCallbackHandler.hpp>
#include <CommonAPI/DBus/DBusProxyConnection.hpp>
+#include <CommonAPI/DBus/DBusErrorEvent.hpp>
namespace CommonAPI {
namespace DBus {
class DBusProxy;
-template< class, class >
+template< class, class... >
struct DBusProxyHelper;
#ifdef WIN32
@@ -76,7 +77,7 @@ struct DBusProxyHelper<In_<DBusInputStream, DBusOutputStream, InArgs_...>,
template <typename DBusProxy_ = DBusProxy>
static void callMethodWithReply(
const DBusProxy_ &_proxy,
- DBusMessage &_message,
+ const DBusMessage &_message,
const CommonAPI::CallInfo *_info,
const InArgs_&... _in,
CommonAPI::CallStatus &_status,
@@ -175,7 +176,7 @@ struct DBusProxyHelper<In_<DBusInputStream, DBusOutputStream, InArgs_...>,
template <typename DBusProxy_ = DBusProxy, typename DelegateFunction_>
static std::future<CallStatus> callMethodAsync(
DBusProxy_ &_proxy,
- DBusMessage &_message,
+ const DBusMessage &_message,
const CommonAPI::CallInfo *_info,
const InArgs_&... _in,
DelegateFunction_ _function,
@@ -221,7 +222,7 @@ struct DBusProxyHelper<In_<DBusInputStream, DBusOutputStream, InArgs_...>,
std::shared_ptr< std::unique_ptr< DBusProxyConnection::DBusMessageReplyAsyncHandler > > sharedDbusMessageReplyAsyncHandler(
new std::unique_ptr< DBusProxyConnection::DBusMessageReplyAsyncHandler >(std::move(dbusMessageReplyAsyncHandler)));
//async isAvailable call with timeout
- COMMONAPI_VERBOSE("MethodAsync(dbus): Proxy not available -> register calback");
+ COMMONAPI_VERBOSE("MethodAsync(dbus): Proxy not available -> register callback");
_proxy.isAvailableAsync([&_proxy, _message, sharedDbusMessageReplyAsyncHandler](
const AvailabilityStatus _status,
const Timeout_t remaining) {
@@ -245,9 +246,9 @@ struct DBusProxyHelper<In_<DBusInputStream, DBusOutputStream, InArgs_...>,
unsigned int dummySerial = 999;
_message.setSerial(dummySerial); //set dummy serial
if (*sharedDbusMessageReplyAsyncHandler) {
- DBusMessage errorMessage = _message.createMethodError(DBUS_ERROR_UNKNOWN_METHOD);
- _proxy.getDBusConnection()->pushDBusMessageReplyToMainLoop(errorMessage,
- std::move(*sharedDbusMessageReplyAsyncHandler));
+ DBusMessage errorMessage = _message.createMethodError(DBUS_ERROR_UNKNOWN_METHOD);
+ _proxy.getDBusConnection()->pushDBusMessageReplyToMainLoop(errorMessage,
+ std::move(*sharedDbusMessageReplyAsyncHandler));
COMMONAPI_VERBOSE("MethodAsync(dbus): Proxy callback not reachable -> sendMessageWithReplyAsync");
} else {
COMMONAPI_ERROR("MethodAsync(dbus): Proxy callback not reachable but callback taken");
@@ -324,6 +325,185 @@ struct DBusProxyHelper<In_<DBusInputStream, DBusOutputStream, InArgs_...>,
}
};
+template<
+ template <class ...> class In_, class... InArgs_,
+ template <class...> class Out_, class... OutArgs_,
+ class... ErrorEvents_>
+struct DBusProxyHelper<In_<DBusInputStream, DBusOutputStream, InArgs_...>,
+ Out_<DBusInputStream, DBusOutputStream, OutArgs_...>,
+ ErrorEvents_...> {
+
+ template <typename DBusProxy_ = DBusProxy>
+ static void callMethodWithReply(
+ const DBusProxy_ &_proxy,
+ const DBusMessage &_message,
+ const CommonAPI::CallInfo *_info,
+ const InArgs_&... _in,
+ CommonAPI::CallStatus &_status,
+ OutArgs_&... _out,
+ const std::tuple<ErrorEvents_*...> &_errorEvents) {
+
+ if (sizeof...(InArgs_) > 0) {
+ DBusOutputStream output(_message);
+ if (!DBusSerializableArguments<InArgs_...>::serialize(output, _in...)) {
+ _status = CallStatus::OUT_OF_MEMORY;
+ return;
+ }
+ output.flush();
+ }
+
+ DBusError error;
+ DBusMessage reply = _proxy.getDBusConnection()->sendDBusMessageWithReplyAndBlock(_message, error, _info);
+ if (error) {
+ DBusErrorEventHelper::notifyListeners(reply,
+ error.getName(),
+ typename make_sequence_range<sizeof...(ErrorEvents_), 0>::type(),
+ _errorEvents);
+ _status = CallStatus::REMOTE_ERROR;
+ return;
+ }
+
+ if (sizeof...(OutArgs_) > 0) {
+ DBusInputStream input(reply);
+ if (!DBusSerializableArguments<OutArgs_...>::deserialize(input, _out...)) {
+ _status = CallStatus::REMOTE_ERROR;
+ return;
+ }
+ }
+ _status = CallStatus::SUCCESS;
+ }
+
+
+ template <typename DBusProxy_ = DBusProxy>
+ static void callMethodWithReply(
+ const DBusProxy_ &_proxy,
+ const std::string &_method,
+ const std::string &_signature,
+ const CommonAPI::CallInfo *_info,
+ const InArgs_&... _in,
+ CommonAPI::CallStatus &_status,
+ OutArgs_&... _out,
+ const std::tuple<ErrorEvents_*...> &_errorEvents){
+#ifndef WIN32
+ static std::mutex callMethodWithReply_mutex_;
+#endif
+ std::lock_guard<std::mutex> lock(callMethodWithReply_mutex_);
+
+ if (_proxy.isAvailable()) {
+ DBusMessage message = _proxy.createMethodCall(_method, _signature);
+ callMethodWithReply(_proxy, message, _info, _in..., _status, _out..., _errorEvents);
+ } else {
+ _status = CallStatus::NOT_AVAILABLE;
+ }
+ }
+
+ template <typename DBusProxy_ = DBusProxy, typename DelegateFunction_>
+ static std::future<CallStatus> callMethodAsync(
+ DBusProxy_ &_proxy,
+ const DBusMessage &_message,
+ const CommonAPI::CallInfo *_info,
+ const InArgs_&... _in,
+ DelegateFunction_ _function,
+ std::tuple<OutArgs_...> _out,
+ const std::tuple<ErrorEvents_*...> &_errorEvents) {
+ if (sizeof...(InArgs_) > 0) {
+ DBusOutputStream output(_message);
+ const bool success = DBusSerializableArguments<
+ InArgs_...
+ >::serialize(output, _in...);
+ if (!success) {
+ std::promise<CallStatus> promise;
+ promise.set_value(CallStatus::OUT_OF_MEMORY);
+ return promise.get_future();
+ }
+ output.flush();
+ }
+
+ typename DBusProxyAsyncCallbackHandler<DBusProxy, OutArgs_...>::Delegate delegate(
+ _proxy.shared_from_this(), _function);
+ auto dbusMessageReplyAsyncHandler = std::move(DBusProxyAsyncCallbackHandler<
+ std::tuple<ErrorEvents_*...>,
+ DBusProxy,
+ OutArgs_...>::create(delegate, _out, _errorEvents));
+
+ std::future<CallStatus> callStatusFuture;
+ try {
+ callStatusFuture = dbusMessageReplyAsyncHandler->getFuture();
+ } catch (std::exception& e) {
+ COMMONAPI_ERROR("MethodAsync(dbus): messageReplyAsyncHandler future failed(", e.what(), ")");
+ }
+
+ if(_proxy.isAvailable()) {
+ if (_proxy.getDBusConnection()->sendDBusMessageWithReplyAsync(
+ _message,
+ std::move(dbusMessageReplyAsyncHandler),
+ _info)){
+ COMMONAPI_VERBOSE("MethodAsync(dbus): Proxy available -> sendMessageWithReplyAsync");
+ return callStatusFuture;
+ } else {
+ return std::future<CallStatus>();
+ }
+ } else {
+ std::shared_ptr< std::unique_ptr< DBusProxyConnection::DBusMessageReplyAsyncHandler > > sharedDbusMessageReplyAsyncHandler(
+ new std::unique_ptr< DBusProxyConnection::DBusMessageReplyAsyncHandler >(std::move(dbusMessageReplyAsyncHandler)));
+ //async isAvailable call with timeout
+ COMMONAPI_VERBOSE("MethodAsync(dbus): Proxy not available -> register callback");
+ _proxy.isAvailableAsync([&_proxy, _message, sharedDbusMessageReplyAsyncHandler](
+ const AvailabilityStatus _status,
+ const Timeout_t remaining) {
+ if(_status == AvailabilityStatus::AVAILABLE) {
+ //create new call info with remaining timeout. Minimal timeout is 100 ms.
+ Timeout_t newTimeout = remaining;
+ if(remaining < 100)
+ newTimeout = 100;
+ CallInfo newInfo(newTimeout);
+ if(*sharedDbusMessageReplyAsyncHandler) {
+ _proxy.getDBusConnection()->sendDBusMessageWithReplyAsync(
+ _message,
+ std::move(*sharedDbusMessageReplyAsyncHandler),
+ &newInfo);
+ COMMONAPI_VERBOSE("MethodAsync(dbus): Proxy callback available -> sendMessageWithReplyAsync");
+ } else {
+ COMMONAPI_ERROR("MethodAsync(dbus): Proxy callback available but callback taken");
+ }
+ } else {
+ //create error message and push it directly to the connection
+ unsigned int dummySerial = 999;
+ _message.setSerial(dummySerial); //set dummy serial
+ if (*sharedDbusMessageReplyAsyncHandler) {
+ DBusMessage errorMessage = _message.createMethodError(DBUS_ERROR_UNKNOWN_METHOD);
+ _proxy.getDBusConnection()->pushDBusMessageReplyToMainLoop(errorMessage,
+ std::move(*sharedDbusMessageReplyAsyncHandler));
+ COMMONAPI_VERBOSE("MethodAsync(dbus): Proxy callback not reachable -> sendMessageWithReplyAsync");
+ } else {
+ COMMONAPI_ERROR("MethodAsync(dbus): Proxy callback not reachable but callback taken");
+ }
+ }
+ }, _info);
+ return callStatusFuture;
+ }
+ }
+
+ template <typename DBusProxy_ = DBusProxy, typename DelegateFunction_>
+ static std::future<CallStatus> callMethodAsync(
+ DBusProxy_ &_proxy,
+ const std::string &_method,
+ const std::string &_signature,
+ const CommonAPI::CallInfo *_info,
+ const InArgs_&... _in,
+ DelegateFunction_ _function,
+ std::tuple<OutArgs_...> _out,
+ const std::tuple<ErrorEvents_*...> &_errorEvents) {
+#ifndef WIN32
+ static std::mutex callMethodAsync_mutex_;
+#endif
+ std::lock_guard<std::mutex> lock(callMethodAsync_mutex_);
+
+ DBusMessage message = _proxy.createMethodCall(_method, _signature);
+ return callMethodAsync(_proxy, message, _info, _in..., _function, _out, _errorEvents);
+ }
+};
+
} // namespace DBus
} // namespace CommonAPI
diff --git a/include/CommonAPI/DBus/DBusSelectiveEvent.hpp b/include/CommonAPI/DBus/DBusSelectiveEvent.hpp
index 1c1ce85..93bb5ea 100644
--- a/include/CommonAPI/DBus/DBusSelectiveEvent.hpp
+++ b/include/CommonAPI/DBus/DBusSelectiveEvent.hpp
@@ -42,7 +42,7 @@ public:
virtual void setSubscriptionToken(const DBusProxyConnection::DBusSignalHandlerToken _subscriptionToken, uint32_t tag) {
this->subscription_ = _subscriptionToken;
- static_cast<DBusProxy&>(this->proxy_).insertSelectiveSubscription(this->name_, this, tag, this->signature_);
+ static_cast<DBusProxy&>(this->proxy_).insertSelectiveSubscription(this->name_, this->signalHandler_, tag, this->signature_);
}
protected:
@@ -53,12 +53,12 @@ protected:
void onListenerAdded(const Listener &_listener, const uint32_t subscription) {
(void) _listener;
static_cast<DBusProxy&>(this->proxy_).subscribeForSelectiveBroadcastOnConnection(
- this->path_, this->interface_, this->name_, this->signature_, this, subscription);
+ this->path_, this->interface_, this->name_, this->signature_, this->signalHandler_, subscription);
}
void onLastListenerRemoved(const Listener &) {
static_cast<DBusProxy&>(this->proxy_).unsubscribeFromSelectiveBroadcast(
- this->name_, this->subscription_, this);
+ this->name_, this->subscription_, this->signalHandler_.get());
}
};
diff --git a/include/CommonAPI/DBus/DBusServiceRegistry.hpp b/include/CommonAPI/DBus/DBusServiceRegistry.hpp
index 00dd355..8a56a91 100644
--- a/include/CommonAPI/DBus/DBusServiceRegistry.hpp
+++ b/include/CommonAPI/DBus/DBusServiceRegistry.hpp
@@ -58,7 +58,7 @@ class DBusServiceRegistry: public std::enable_shared_from_this<DBusServiceRegist
};
// template class DBusServiceListener<> { typedef functor; typedef list; typedef subscription }
- typedef std::function<void(const AvailabilityStatus& availabilityStatus)> DBusServiceListener;
+ typedef std::function<void(std::shared_ptr<DBusProxy>, const AvailabilityStatus& availabilityStatus)> DBusServiceListener;
typedef std::list<DBusServiceListener> DBusServiceListenerList;
typedef DBusServiceListenerList::iterator DBusServiceSubscription;
@@ -82,7 +82,8 @@ class DBusServiceRegistry: public std::enable_shared_from_this<DBusServiceRegist
void init();
DBusServiceSubscription subscribeAvailabilityListener(const std::string &_address,
- DBusServiceListener _listener);
+ DBusServiceListener _listener,
+ std::weak_ptr<DBusProxy> _proxy);
void unsubscribeAvailabilityListener(const std::string &_address,
DBusServiceSubscription &_listener);
@@ -114,12 +115,14 @@ class DBusServiceRegistry: public std::enable_shared_from_this<DBusServiceRegist
DBusInterfaceNameListenersRecord(DBusInterfaceNameListenersRecord &&_other)
: state(_other.state),
listenerList(std::move(_other.listenerList)),
- listenersToRemove(std::move(_other.listenersToRemove)) {
+ listenersToRemove(std::move(_other.listenersToRemove)),
+ proxy(_other.proxy){
}
DBusRecordState state;
DBusServiceListenerList listenerList;
std::list<DBusServiceSubscription> listenersToRemove;
+ std::weak_ptr<DBusProxy> proxy;
};
typedef std::unordered_map<std::string, DBusInterfaceNameListenersRecord> DBusInterfaceNameListenersMap;
@@ -307,9 +310,14 @@ class DBusServiceRegistry: public std::enable_shared_from_this<DBusServiceRegist
private:
typedef std::map<std::shared_ptr<DBusProxyConnection>, std::shared_ptr<DBusServiceRegistry>> RegistryMap_t;
- static RegistryMap_t registries_;
+ static std::shared_ptr<RegistryMap_t> getRegistryMap() {
+ static std::shared_ptr<RegistryMap_t> registries(new RegistryMap_t);
+ return registries;
+ }
static std::mutex registriesMutex_;
+ std::shared_ptr<RegistryMap_t> registries_;
std::shared_ptr<DBusAddressTranslator> translator_;
+ std::weak_ptr<DBusServiceRegistry> selfReference_;
};
diff --git a/include/CommonAPI/DBus/DBusStubAdapterHelper.hpp b/include/CommonAPI/DBus/DBusStubAdapterHelper.hpp
index 59d33bc..3a9b7e8 100644
--- a/include/CommonAPI/DBus/DBusStubAdapterHelper.hpp
+++ b/include/CommonAPI/DBus/DBusStubAdapterHelper.hpp
@@ -487,8 +487,7 @@ class DBusMethodStubDispatcher<StubClass_, In_<InArgs_...>, DeplIn_<DeplIn_Args.
std::tuple<CommonAPI::Deployable<InArgs_, DeplIn_Args>...> in_;
};
-
-template< class, class, class, class, class>
+template< class, class, class, class, class...>
class DBusMethodWithReplyStubDispatcher;
template <
@@ -503,76 +502,95 @@ class DBusMethodWithReplyStubDispatcher<
In_<InArgs_...>,
Out_<OutArgs_...>,
DeplIn_<DeplIn_Args...>,
- DeplOut_<DeplOutArgs_...> >:
+ DeplOut_<DeplOutArgs_...>>:
public StubDispatcher<StubClass_> {
public:
typedef typename StubClass_::RemoteEventHandlerType RemoteEventHandlerType;
typedef std::function<void (OutArgs_...)> ReplyType_t;
+
typedef void (StubClass_::*StubFunctor_)(
std::shared_ptr<CommonAPI::ClientId>, InArgs_..., ReplyType_t);
- DBusMethodWithReplyStubDispatcher(StubFunctor_ stubFunctor,
- const char* dbusReplySignature,
- std::tuple<DeplIn_Args*...> _inDepArgs,
- std::tuple<DeplOutArgs_*...> _outDepArgs):
- stubFunctor_(stubFunctor),
- dbusReplySignature_(dbusReplySignature),
+ DBusMethodWithReplyStubDispatcher(StubFunctor_ _stubFunctor,
+ const char* _dbusReplySignature,
+ const std::tuple<DeplIn_Args*...>& _inDepArgs,
+ const std::tuple<DeplOutArgs_*...>& _outDepArgs):
out_(_outDepArgs),
- currentCall_(0) {
+ currentCall_(0),
+ stubFunctor_(_stubFunctor),
+ dbusReplySignature_(_dbusReplySignature) {
initialize(typename make_sequence_range<sizeof...(DeplIn_Args), 0>::type(), _inDepArgs);
-
}
- bool dispatchDBusMessage(const DBusMessage& dbusMessage,
- const std::shared_ptr<StubClass_>& stub,
+ bool dispatchDBusMessage(const DBusMessage& _dbusMessage,
+ const std::shared_ptr<StubClass_>& _stub,
RemoteEventHandlerType* _remoteEventHandler,
std::weak_ptr<DBusProxyConnection> _connection) {
(void) _remoteEventHandler;
connection_ = _connection;
return handleDBusMessage(
- dbusMessage,
- stub,
- typename make_sequence_range<sizeof...(InArgs_), 0>::type(),
- typename make_sequence_range<sizeof...(OutArgs_), 0>::type());
+ _dbusMessage,
+ _stub,
+ typename make_sequence_range<sizeof...(InArgs_), 0>::type(),
+ typename make_sequence_range<sizeof...(OutArgs_), 0>::type());
}
- bool sendReply(CommonAPI::CallId_t _call,
- std::tuple<CommonAPI::Deployable<OutArgs_, DeplOutArgs_>...> args = std::make_tuple()) {
+ bool sendReply(const CommonAPI::CallId_t _call,
+ const std::tuple<CommonAPI::Deployable<OutArgs_, DeplOutArgs_>...> args = std::make_tuple()) {
+ {
+ std::lock_guard<std::mutex> lock(mutex_);
+ auto dbusMessage = pending_.find(_call);
+ if(dbusMessage != pending_.end()) {
+ DBusMessage reply = dbusMessage->second.createMethodReturn(dbusReplySignature_);
+ pending_[_call] = reply;
+ } else {
+ return false;
+ }
+ }
return sendReplyInternal(_call, typename make_sequence_range<sizeof...(OutArgs_), 0>::type(), args);
}
+protected:
+
+ std::tuple<CommonAPI::Deployable<InArgs_, DeplIn_Args>...> in_;
+ std::tuple<DeplOutArgs_*...> out_;
+ CommonAPI::CallId_t currentCall_;
+ std::map<CommonAPI::CallId_t, DBusMessage> pending_;
+ std::mutex mutex_; // protects pending_
+
+ std::weak_ptr<DBusProxyConnection> connection_;
+
private:
template <int... DeplIn_ArgIndices>
- inline void initialize(index_sequence<DeplIn_ArgIndices...>, std::tuple<DeplIn_Args*...> &_in) {
+ inline void initialize(index_sequence<DeplIn_ArgIndices...>, const std::tuple<DeplIn_Args*...>& _in) {
in_ = std::make_tuple(std::get<DeplIn_ArgIndices>(_in)...);
}
template <int... InArgIndices_, int... OutArgIndices_>
- inline bool handleDBusMessage(const DBusMessage& dbusMessage,
- const std::shared_ptr<StubClass_>& stub,
+ inline bool handleDBusMessage(const DBusMessage& _dbusMessage,
+ const std::shared_ptr<StubClass_>& _stub,
index_sequence<InArgIndices_...>,
index_sequence<OutArgIndices_...>) {
if (sizeof...(DeplIn_Args) > 0) {
- DBusInputStream dbusInputStream(dbusMessage);
+ DBusInputStream dbusInputStream(_dbusMessage);
const bool success = DBusSerializableArguments<CommonAPI::Deployable<InArgs_, DeplIn_Args>...>::deserialize(dbusInputStream, std::get<InArgIndices_>(in_)...);
if (!success)
return false;
}
std::shared_ptr<DBusClientId> clientId
- = std::make_shared<DBusClientId>(std::string(dbusMessage.getSender()));
- DBusMessage reply = dbusMessage.createMethodReturn(dbusReplySignature_);
+ = std::make_shared<DBusClientId>(std::string(_dbusMessage.getSender()));
CommonAPI::CallId_t call;
{
std::lock_guard<std::mutex> lock(mutex_);
call = currentCall_++;
- pending_[call] = reply;
+ pending_[call] = _dbusMessage;
}
- (stub.get()->*stubFunctor_)(
+ (_stub.get()->*stubFunctor_)(
clientId,
std::move(std::get<InArgIndices_>(in_).getValue())...,
[call, this](OutArgs_... _args){
@@ -582,21 +600,21 @@ private:
}
);
- return true;
+ return true;
}
template<int... OutArgIndices_>
- bool sendReplyInternal(CommonAPI::CallId_t _call,
+ bool sendReplyInternal(const CommonAPI::CallId_t _call,
index_sequence<OutArgIndices_...>,
- std::tuple<CommonAPI::Deployable<OutArgs_, DeplOutArgs_>...> args) {
+ const std::tuple<CommonAPI::Deployable<OutArgs_, DeplOutArgs_>...>& _args) {
std::lock_guard<std::mutex> lock(mutex_);
auto reply = pending_.find(_call);
if (reply != pending_.end()) {
if (sizeof...(DeplOutArgs_) > 0) {
DBusOutputStream output(reply->second);
if (!DBusSerializableArguments<CommonAPI::Deployable<OutArgs_, DeplOutArgs_>...>::serialize(
- output, std::get<OutArgIndices_>(args)...)) {
- (void)args;
+ output, std::get<OutArgIndices_>(_args)...)) {
+ (void)_args;
pending_.erase(_call);
return false;
}
@@ -616,14 +634,157 @@ private:
StubFunctor_ stubFunctor_;
const char* dbusReplySignature_;
+};
- std::tuple<CommonAPI::Deployable<InArgs_, DeplIn_Args>...> in_;
- std::tuple<DeplOutArgs_*...> out_;
- CommonAPI::CallId_t currentCall_;
- std::map<CommonAPI::CallId_t, DBusMessage> pending_;
- std::mutex mutex_; // protects pending_
+template <
+ typename StubClass_,
+ template <class...> class In_, class... InArgs_,
+ template <class...> class Out_, class... OutArgs_,
+ template <class...> class DeplIn_, class... DeplIn_Args,
+ template <class...> class DeplOut_, class... DeplOutArgs_,
+ class... ErrorReplies_>
- std::weak_ptr<DBusProxyConnection> connection_;
+class DBusMethodWithReplyStubDispatcher<
+ StubClass_,
+ In_<InArgs_...>,
+ Out_<OutArgs_...>,
+ DeplIn_<DeplIn_Args...>,
+ DeplOut_<DeplOutArgs_...>,
+ ErrorReplies_...> :
+ public DBusMethodWithReplyStubDispatcher<
+ StubClass_,
+ In_<InArgs_...>,
+ Out_<OutArgs_...>,
+ DeplIn_<DeplIn_Args...>,
+ DeplOut_<DeplOutArgs_...>> {
+ public:
+ typedef typename StubClass_::RemoteEventHandlerType RemoteEventHandlerType;
+ typedef std::function<void (OutArgs_...)> ReplyType_t;
+
+ typedef void (StubClass_::*StubFunctor_)(
+ std::shared_ptr<CommonAPI::ClientId>, CommonAPI::CallId_t, InArgs_..., ReplyType_t, ErrorReplies_...);
+
+ DBusMethodWithReplyStubDispatcher(StubFunctor_ _stubFunctor,
+ const char* _dbusReplySignature,
+ const std::tuple<DeplIn_Args*...>& _inDepArgs,
+ const std::tuple<DeplOutArgs_*...>& _outDepArgs,
+ const ErrorReplies_... _errorReplies) :
+ DBusMethodWithReplyStubDispatcher<
+ StubClass_,
+ In_<InArgs_...>,
+ Out_<OutArgs_...>,
+ DeplIn_<DeplIn_Args...>,
+ DeplOut_<DeplOutArgs_...>>(
+ NULL,
+ _dbusReplySignature,
+ _inDepArgs,
+ _outDepArgs),
+ stubFunctor_(_stubFunctor),
+ errorReplies_(std::make_tuple(_errorReplies...)) { }
+
+ bool dispatchDBusMessage(const DBusMessage& _dbusMessage,
+ const std::shared_ptr<StubClass_>& _stub,
+ RemoteEventHandlerType* _remoteEventHandler,
+ std::weak_ptr<DBusProxyConnection> _connection) {
+ (void) _remoteEventHandler;
+ this->connection_ = _connection;
+ return handleDBusMessage(
+ _dbusMessage,
+ _stub,
+ typename make_sequence_range<sizeof...(InArgs_), 0>::type(),
+ typename make_sequence_range<sizeof...(OutArgs_), 0>::type(),
+ typename make_sequence_range<sizeof...(ErrorReplies_), 0>::type());
+ }
+
+ template <class... ErrorReplyOutArgs_, class... ErrorReplyDeplOutArgs_>
+ bool sendErrorReply(const CommonAPI::CallId_t _call,
+ const std::string &_signature,
+ const std::string &_errorName,
+ const std::tuple<CommonAPI::Deployable<ErrorReplyOutArgs_, ErrorReplyDeplOutArgs_>...>& _args) {
+ {
+ std::lock_guard<std::mutex> lock(this->mutex_);
+ auto dbusMessage = this->pending_.find(_call);
+ if(dbusMessage != this->pending_.end()) {
+ DBusMessage reply = dbusMessage->second.createMethodError(_errorName, _signature);
+ this->pending_[_call] = reply;
+ } else {
+ return false;
+ }
+ }
+ return sendErrorReplyInternal(_call, typename make_sequence_range<sizeof...(ErrorReplyOutArgs_), 0>::type(), _args);
+ }
+
+private:
+
+ template <int... InArgIndices_, int... OutArgIndices_, int... ErrorRepliesIndices_>
+ inline bool handleDBusMessage(const DBusMessage& _dbusMessage,
+ const std::shared_ptr<StubClass_>& _stub,
+ index_sequence<InArgIndices_...>,
+ index_sequence<OutArgIndices_...>,
+ index_sequence<ErrorRepliesIndices_...>) {
+ if (sizeof...(DeplIn_Args) > 0) {
+ DBusInputStream dbusInputStream(_dbusMessage);
+ const bool success = DBusSerializableArguments<CommonAPI::Deployable<InArgs_, DeplIn_Args>...>::deserialize(dbusInputStream, std::get<InArgIndices_>(this->in_)...);
+ if (!success)
+ return false;
+ }
+
+ std::shared_ptr<DBusClientId> clientId
+ = std::make_shared<DBusClientId>(std::string(_dbusMessage.getSender()));
+
+ CommonAPI::CallId_t call;
+ {
+ std::lock_guard<std::mutex> lock(this->mutex_);
+ call = this->currentCall_++;
+ this->pending_[call] = _dbusMessage;
+ }
+
+ (_stub.get()->*stubFunctor_)(
+ clientId,
+ call,
+ std::move(std::get<InArgIndices_>(this->in_).getValue())...,
+ [call, this](OutArgs_... _args){
+ this->sendReply(call, std::make_tuple(CommonAPI::Deployable<OutArgs_, DeplOutArgs_>(
+ _args, std::get<OutArgIndices_>(this->out_)
+ )...));
+ },
+ std::get<ErrorRepliesIndices_>(errorReplies_)...
+ );
+
+ return true;
+ }
+
+ template<int... ErrorReplyOutArgIndices_, class... ErrorReplyOutArgs_, class ...ErrorReplyDeplOutArgs_>
+ bool sendErrorReplyInternal(CommonAPI::CallId_t _call,
+ index_sequence<ErrorReplyOutArgIndices_...>,
+ const std::tuple<CommonAPI::Deployable<ErrorReplyOutArgs_, ErrorReplyDeplOutArgs_>...>& _args) {
+ std::lock_guard<std::mutex> lock(this->mutex_);
+ auto reply = this->pending_.find(_call);
+ if (reply != this->pending_.end()) {
+ if (sizeof...(ErrorReplyDeplOutArgs_) > 0) {
+ DBusOutputStream output(reply->second);
+ if (!DBusSerializableArguments<CommonAPI::Deployable<ErrorReplyOutArgs_, ErrorReplyDeplOutArgs_>...>::serialize(
+ output, std::get<ErrorReplyOutArgIndices_>(_args)...)) {
+ (void)_args;
+ this->pending_.erase(_call);
+ return false;
+ }
+ output.flush();
+ }
+ if (std::shared_ptr<DBusProxyConnection> connection = this->connection_.lock()) {
+ bool isSuccessful = connection->sendDBusMessage(reply->second);
+ this->pending_.erase(_call);
+ return isSuccessful;
+ }
+ else {
+ return false;
+ }
+ }
+ return false;
+ }
+
+ StubFunctor_ stubFunctor_;
+ std::tuple<ErrorReplies_...> errorReplies_;
};
template< class, class, class, class >
diff --git a/include/murmurhash/MurmurHash3.h b/include/murmurhash/MurmurHash3.h
index a7e45a7..d6b2c5d 100644
--- a/include/murmurhash/MurmurHash3.h
+++ b/include/murmurhash/MurmurHash3.h
@@ -26,11 +26,11 @@ typedef unsigned __int64 uint64_t;
//-----------------------------------------------------------------------------
-void MurmurHash3_x86_32 ( const void * key, int len, uint32_t seed, void * out );
+void MurmurHash3_x86_32 ( const void * key, unsigned int len, uint32_t seed, void * out );
-void MurmurHash3_x86_128 ( const void * key, int len, uint32_t seed, void * out );
+void MurmurHash3_x86_128 ( const void * key, unsigned int len, uint32_t seed, void * out );
-void MurmurHash3_x64_128 ( const void * key, int len, uint32_t seed, void * out );
+void MurmurHash3_x64_128 ( const void * key, unsigned int len, uint32_t seed, void * out );
//-----------------------------------------------------------------------------
diff --git a/src/CommonAPI/DBus/DBusConnection.cpp b/src/CommonAPI/DBus/DBusConnection.cpp
index 23967a9..f34ff70 100644
--- a/src/CommonAPI/DBus/DBusConnection.cpp
+++ b/src/CommonAPI/DBus/DBusConnection.cpp
@@ -124,19 +124,13 @@ DBusConnection::~DBusConnection() {
dbus_connection_set_timeout_functions(connection_, NULL, NULL, NULL, NULL, NULL);
}
- lockedContext->deregisterWatch(queueWatch_);
lockedContext->deregisterDispatchSource(queueDispatchSource_);
lockedContext->deregisterDispatchSource(dispatchSource_);
+ lockedContext->deregisterWatch(queueWatch_);
delete watchContext_;
delete timeoutContext_;
}
- // ensure, the registry survives until disconnecting is done...
- //std::shared_ptr<DBusServiceRegistry> itsRegistry = DBusServiceRegistry::get(shared_from_this());
-
- // Disconnecting not possible because of circular dependency, the destructor will be called AFTER disconnect anyway.
- //disconnect();
-
//Assert that the enforcerThread_ is in a position to finish itself correctly even after destruction
//of the DBusConnection. Also assert all resources are cleaned up.
auto it = timeoutMap_.begin();
@@ -916,11 +910,6 @@ DBusMessage DBusConnection::sendDBusMessageWithReplyAndBlock(const DBusMessage&
COMMONAPI_DEBUG("Message sent: SenderID: ", _info->sender_, " - Serial number: ", dbusMessage.getSerial());
}
- if (dbusError) {
- COMMONAPI_ERROR(std::string(__FUNCTION__), "dbusError set");
- return DBusMessage();
- }
-
const bool increaseLibdbusMessageReferenceCount = false;
return DBusMessage(libdbusMessageReply, increaseLibdbusMessageReferenceCount);
}
@@ -1020,8 +1009,11 @@ bool DBusConnection::setDispatching(bool _isDispatching) {
}
}
-void DBusConnection::sendPendingSelectiveSubscription(DBusProxy* callingProxy, std::string interfaceMemberName,
- DBusSignalHandler* dbusSignalHandler, uint32_t tag, std::string interfaceMemberSignature) {
+void DBusConnection::sendPendingSelectiveSubscription(DBusProxy* callingProxy,
+ std::string interfaceMemberName,
+ std::weak_ptr<DBusSignalHandler> dbusSignalHandler,
+ uint32_t tag,
+ std::string interfaceMemberSignature) {
bool outarg;
std::string methodName = "subscribeFor" + interfaceMemberName + "Selective";
DBusProxyHelper<CommonAPI::DBus::DBusSerializableArguments<>,
@@ -1032,14 +1024,17 @@ void DBusConnection::sendPendingSelectiveSubscription(DBusProxy* callingProxy, s
(const CommonAPI::CallStatus& callStatus, const bool& accepted) {
if (callStatus == CommonAPI::CallStatus::SUCCESS && accepted) {
- dbusSignalHandler->onSpecificError(CommonAPI::CallStatus::SUCCESS, tag);
+ if(auto itsHandler = dbusSignalHandler.lock())
+ itsHandler->onSpecificError(CommonAPI::CallStatus::SUCCESS, tag);
} else {
const DBusSignalHandlerPath itsToken(callingProxy->getDBusAddress().getObjectPath(),
callingProxy->getDBusAddress().getInterface(),
interfaceMemberName,
interfaceMemberSignature);
- removeSignalMemberHandler(itsToken, dbusSignalHandler);
- dbusSignalHandler->onSpecificError(CommonAPI::CallStatus::SUBSCRIPTION_REFUSED, tag);
+ if(auto itsHandler = dbusSignalHandler.lock()) {
+ removeSignalMemberHandler(itsToken, itsHandler.get());
+ itsHandler->onSpecificError(CommonAPI::CallStatus::SUBSCRIPTION_REFUSED, tag);
+ }
}
}, std::make_tuple(outarg));
}
@@ -1049,43 +1044,50 @@ void DBusConnection::subscribeForSelectiveBroadcast(
const std::string& interfaceName,
const std::string& interfaceMemberName,
const std::string& interfaceMemberSignature,
- DBusSignalHandler* dbusSignalHandler,
+ std::weak_ptr<DBusSignalHandler> dbusSignalHandler,
DBusProxy* callingProxy,
uint32_t tag) {
- std::string methodName = "subscribeFor" + interfaceMemberName + "Selective";
-
- DBusProxyConnection::DBusSignalHandlerToken token = addSignalMemberHandler(
- objectPath,
- interfaceName,
- interfaceMemberName,
- interfaceMemberSignature,
- dbusSignalHandler,
- true
- );
- dbusSignalHandler->setSubscriptionToken(token, tag);
-
- bool outarg;
- if(callingProxy->isAvailable()) {
- DBusProxyHelper<CommonAPI::DBus::DBusSerializableArguments<>,
- CommonAPI::DBus::DBusSerializableArguments<bool>>::callMethodAsync(
- *callingProxy, methodName.c_str(), "",
- &CommonAPI::DBus::defaultCallInfo,
- [this, objectPath, interfaceName, interfaceMemberName, interfaceMemberSignature, dbusSignalHandler, callingProxy, tag, token]
- (const CommonAPI::CallStatus& callStatus, const bool& accepted) {
- (void)callStatus;
- if (accepted) {
- dbusSignalHandler->onSpecificError(CommonAPI::CallStatus::SUCCESS, tag);
- } else {
- removeSignalMemberHandler(token, dbusSignalHandler);
- dbusSignalHandler->onSpecificError(CommonAPI::CallStatus::SUBSCRIPTION_REFUSED, tag);
- }
- }, std::make_tuple(outarg));
+ if(auto itsHandler = dbusSignalHandler.lock()) {
+
+ std::string methodName = "subscribeFor" + interfaceMemberName + "Selective";
+
+ DBusSignalHandlerToken token = addSignalMemberHandler(
+ objectPath,
+ interfaceName,
+ interfaceMemberName,
+ interfaceMemberSignature,
+ dbusSignalHandler,
+ true
+ );
+
+ itsHandler->setSubscriptionToken(token, tag);
+
+ bool outarg;
+ if(callingProxy->isAvailable()) {
+ DBusProxyHelper<CommonAPI::DBus::DBusSerializableArguments<>,
+ CommonAPI::DBus::DBusSerializableArguments<bool>>::callMethodAsync(
+ *callingProxy, methodName.c_str(), "",
+ &CommonAPI::DBus::defaultCallInfo,
+ [this, objectPath, interfaceName, interfaceMemberName, interfaceMemberSignature, dbusSignalHandler, callingProxy, tag, token]
+ (const CommonAPI::CallStatus& callStatus, const bool& accepted) {
+ (void)callStatus;
+ if (accepted) {
+ if(auto itsHandler = dbusSignalHandler.lock())
+ itsHandler->onSpecificError(CommonAPI::CallStatus::SUCCESS, tag);
+ } else {
+ if(auto itsHandler = dbusSignalHandler.lock()) {
+ removeSignalMemberHandler(token, itsHandler.get());
+ itsHandler->onSpecificError(CommonAPI::CallStatus::SUBSCRIPTION_REFUSED, tag);
+ }
+ }
+ }, std::make_tuple(outarg));
+ }
}
}
void DBusConnection::unsubscribeFromSelectiveBroadcast(const std::string& eventName,
- DBusProxyConnection::DBusSignalHandlerToken subscription,
+ DBusSignalHandlerToken subscription,
DBusProxy* callingProxy,
const DBusSignalHandler* dbusSignalHandler) {
bool lastListenerOnConnectionRemoved = removeSignalMemberHandler(subscription, dbusSignalHandler);
@@ -1104,7 +1106,7 @@ DBusProxyConnection::DBusSignalHandlerToken DBusConnection::addSignalMemberHandl
const std::string& interfaceName,
const std::string& interfaceMemberName,
const std::string& interfaceMemberSignature,
- DBusSignalHandler* dbusSignalHandler,
+ std::weak_ptr<DBusSignalHandler> dbusSignalHandler,
const bool justAddFilter) {
DBusSignalHandlerPath dbusSignalHandlerPath(
objectPath,
@@ -1115,18 +1117,20 @@ DBusProxyConnection::DBusSignalHandlerToken DBusConnection::addSignalMemberHandl
auto signalEntry = dbusSignalHandlerTable_.find(dbusSignalHandlerPath);
const bool isFirstSignalMemberHandler = (signalEntry == dbusSignalHandlerTable_.end());
- if (isFirstSignalMemberHandler) {
+ auto itsHandler = dbusSignalHandler.lock();
+ if (itsHandler && isFirstSignalMemberHandler) {
addLibdbusSignalMatchRule(objectPath, interfaceName, interfaceMemberName, justAddFilter);
- std::set<DBusSignalHandler*> handlerList;
- handlerList.insert(dbusSignalHandler);
+
+ std::map<DBusSignalHandler*, std::weak_ptr<DBusSignalHandler>> handlerList;
+ handlerList[itsHandler.get()] = dbusSignalHandler;
dbusSignalHandlerTable_.insert( {
dbusSignalHandlerPath,
std::make_pair(std::make_shared<std::recursive_mutex>(), std::move(handlerList))
} );
- } else {
+ } else if (itsHandler && !isFirstSignalMemberHandler) {
signalEntry->second.first->lock();
- signalEntry->second.second.insert(dbusSignalHandler);
+ signalEntry->second.second[itsHandler.get()] = dbusSignalHandler;
signalEntry->second.first->unlock();
}
@@ -1134,7 +1138,7 @@ DBusProxyConnection::DBusSignalHandlerToken DBusConnection::addSignalMemberHandl
}
bool DBusConnection::removeSignalMemberHandler(const DBusSignalHandlerToken &dbusSignalHandlerToken,
- const DBusSignalHandler *dbusSignalHandler) {
+ const DBusSignalHandler* dbusSignalHandler) {
bool lastHandlerRemoved = false;
std::lock_guard < std::mutex > dbusSignalLock(signalGuard_);
@@ -1161,41 +1165,43 @@ bool DBusConnection::removeSignalMemberHandler(const DBusSignalHandlerToken &dbu
}
bool DBusConnection::addObjectManagerSignalMemberHandler(const std::string& dbusBusName,
- DBusSignalHandler* dbusSignalHandler) {
+ std::weak_ptr<DBusSignalHandler> dbusSignalHandler) {
if (dbusBusName.length() < 2) {
return false;
}
- std::lock_guard<std::mutex> dbusSignalLock(dbusObjectManagerSignalGuard_);
+ if(auto itsHandler = dbusSignalHandler.lock()) {
+ std::lock_guard<std::mutex> dbusSignalLock(dbusObjectManagerSignalGuard_);
- auto dbusSignalMatchRuleIterator = dbusObjectManagerSignalMatchRulesMap_.find(dbusBusName);
- const bool isDBusSignalMatchRuleFound = (dbusSignalMatchRuleIterator != dbusObjectManagerSignalMatchRulesMap_.end());
+ auto dbusSignalMatchRuleIterator = dbusObjectManagerSignalMatchRulesMap_.find(dbusBusName);
+ const bool isDBusSignalMatchRuleFound = (dbusSignalMatchRuleIterator != dbusObjectManagerSignalMatchRulesMap_.end());
- if (!isDBusSignalMatchRuleFound) {
- if (isConnected() && !addObjectManagerSignalMatchRule(dbusBusName)) {
- return false;
- }
+ if (!isDBusSignalMatchRuleFound) {
+ if (isConnected() && !addObjectManagerSignalMatchRule(dbusBusName)) {
+ return false;
+ }
- auto insertResult = dbusObjectManagerSignalMatchRulesMap_.insert({ dbusBusName, 0 });
- const bool isInsertSuccessful = insertResult.second;
+ auto insertResult = dbusObjectManagerSignalMatchRulesMap_.insert({ dbusBusName, 0 });
+ const bool isInsertSuccessful = insertResult.second;
- if (!isInsertSuccessful) {
- if (isConnected()) {
- const bool isRemoveSignalMatchRuleSuccessful = removeObjectManagerSignalMatchRule(dbusBusName);
- if (!isRemoveSignalMatchRuleSuccessful) {
- COMMONAPI_ERROR(std::string(__FUNCTION__), " removeObjectManagerSignalMatchRule", dbusBusName, " failed");
+ if (!isInsertSuccessful) {
+ if (isConnected()) {
+ const bool isRemoveSignalMatchRuleSuccessful = removeObjectManagerSignalMatchRule(dbusBusName);
+ if (!isRemoveSignalMatchRuleSuccessful) {
+ COMMONAPI_ERROR(std::string(__FUNCTION__), " removeObjectManagerSignalMatchRule", dbusBusName, " failed");
+ }
}
+ return false;
}
- return false;
+
+ dbusSignalMatchRuleIterator = insertResult.first;
}
- dbusSignalMatchRuleIterator = insertResult.first;
+ size_t &dbusSignalMatchRuleReferenceCount = dbusSignalMatchRuleIterator->second;
+ dbusSignalMatchRuleReferenceCount++;
+ dbusObjectManagerSignalHandlerTable_.insert( { dbusBusName, std::make_pair(itsHandler.get(), dbusSignalHandler) } );
}
- size_t &dbusSignalMatchRuleReferenceCount = dbusSignalMatchRuleIterator->second;
- dbusSignalMatchRuleReferenceCount++;
- dbusObjectManagerSignalHandlerTable_.insert( { dbusBusName, dbusSignalHandler } );
-
return true;
}
@@ -1219,7 +1225,7 @@ bool DBusConnection::removeObjectManagerSignalMemberHandler(const std::string& d
auto dbusObjectManagerSignalHandlerIterator = std::find_if(
dbusObjectManagerSignalHandlerRange.first,
dbusObjectManagerSignalHandlerRange.second,
- [&](decltype(*dbusObjectManagerSignalHandlerRange.first)& it) { return it.second == dbusSignalHandler; });
+ [&](decltype(*dbusObjectManagerSignalHandlerRange.first)& it) { return it.second.first == dbusSignalHandler; });
const bool isDBusSignalHandlerFound = (dbusObjectManagerSignalHandlerIterator != dbusObjectManagerSignalHandlerRange.second);
if (!isDBusSignalHandlerFound) {
return false;
@@ -1574,8 +1580,9 @@ void notifyDBusSignalHandlers(DBusSignalHandlersTable& dbusSignalHandlerstable,
auto handlerEntry = signalEntry->second.second.begin();
while (handlerEntry != signalEntry->second.second.end()) {
- DBusProxyConnection::DBusSignalHandler* dbusSignalHandler = *handlerEntry;
- dbusSignalHandler->onSignalDBusMessage(dbusMessage);
+ std::weak_ptr<DBusProxyConnection::DBusSignalHandler> dbusSignalHandler = handlerEntry->second;
+ if(auto itsHandler = dbusSignalHandler.lock())
+ itsHandler->onSignalDBusMessage(dbusMessage);
handlerEntry++;
}
dbusHandlerResult = DBUS_HANDLER_RESULT_HANDLED;
@@ -1593,8 +1600,9 @@ void notifyDBusOMSignalHandlers(DBusSignalHandlersTable& dbusSignalHandlerstable
dbusHandlerResult = DBUS_HANDLER_RESULT_HANDLED;
}
while (equalRange.first != equalRange.second) {
- DBusProxyConnection::DBusSignalHandler* dbusSignalHandler = equalRange.first->second;
- dbusSignalHandler->onSignalDBusMessage(dbusMessage);
+ std::weak_ptr<DBusProxyConnection::DBusSignalHandler> dbusSignalHandler = equalRange.first->second.second;
+ if(auto itsHandler = dbusSignalHandler.lock())
+ itsHandler->onSignalDBusMessage(dbusMessage);
equalRange.first++;
}
}
diff --git a/src/CommonAPI/DBus/DBusFunctionalHash.cpp b/src/CommonAPI/DBus/DBusFunctionalHash.cpp
index e82d578..5e11bfc 100644
--- a/src/CommonAPI/DBus/DBusFunctionalHash.cpp
+++ b/src/CommonAPI/DBus/DBusFunctionalHash.cpp
@@ -33,10 +33,10 @@ size_t hash<pair<const char*, const char*> >::operator()(const pair<const char*,
uint32_t seed = static_cast<uint32_t>(SMHASHER_SEED_VALUE);
if (NULL != a) {
- MurmurHash3_x86_32(a, static_cast<int>(strlen(a)), seed, &seed);
+ MurmurHash3_x86_32(a, static_cast<unsigned int>(strlen(a)), seed, &seed);
}
if (NULL != b) {
- MurmurHash3_x86_32(b, static_cast<int>(strlen(b)), seed, &seed);
+ MurmurHash3_x86_32(b, static_cast<unsigned int>(strlen(b)), seed, &seed);
}
return static_cast<size_t>(seed);
@@ -44,7 +44,7 @@ size_t hash<pair<const char*, const char*> >::operator()(const pair<const char*,
size_t hash<const char*>::operator()(const char* const t) const {
uint32_t seed = static_cast<uint32_t>(SMHASHER_SEED_VALUE);
- MurmurHash3_x86_32(t, static_cast<int>(strlen(t)), seed, &seed);
+ MurmurHash3_x86_32(t, static_cast<unsigned int>(strlen(t)), seed, &seed);
return static_cast<size_t>(seed);
}
@@ -53,8 +53,8 @@ size_t hash<pair<string, string> >::operator()(const pair<string, string>& t) co
const string& b = t.second;
uint32_t seed = static_cast<uint32_t>(SMHASHER_SEED_VALUE);
- MurmurHash3_x86_32(a.c_str(), static_cast<int>(a.length()), seed, &seed);
- MurmurHash3_x86_32(b.c_str(), static_cast<int>(b.length()), seed, &seed);
+ MurmurHash3_x86_32(a.c_str(), static_cast<unsigned int>(a.length()), seed, &seed);
+ MurmurHash3_x86_32(b.c_str(), static_cast<unsigned int>(b.length()), seed, &seed);
return static_cast<size_t>(seed);
}
@@ -65,9 +65,9 @@ size_t hash<tuple<string, string, string> >::operator()(const tuple<string, stri
const string& c = get<2>(t);
uint32_t seed = static_cast<uint32_t>(SMHASHER_SEED_VALUE);
- MurmurHash3_x86_32(a.c_str(), static_cast<int>(a.length()), seed, &seed);
- MurmurHash3_x86_32(b.c_str(), static_cast<int>(b.length()), seed, &seed);
- MurmurHash3_x86_32(c.c_str(), static_cast<int>(c.length()), seed, &seed);
+ MurmurHash3_x86_32(a.c_str(), static_cast<unsigned int>(a.length()), seed, &seed);
+ MurmurHash3_x86_32(b.c_str(), static_cast<unsigned int>(b.length()), seed, &seed);
+ MurmurHash3_x86_32(c.c_str(), static_cast<unsigned int>(c.length()), seed, &seed);
return static_cast<size_t>(seed);
}
@@ -79,9 +79,9 @@ size_t hash<tuple<string, string, string, bool> >::operator()(const tuple<string
const bool d = get<3>(t);
uint32_t seed = static_cast<uint32_t>(SMHASHER_SEED_VALUE);
- MurmurHash3_x86_32(a.c_str(), static_cast<int>(a.length()), seed, &seed);
- MurmurHash3_x86_32(b.c_str(), static_cast<int>(b.length()), seed, &seed);
- MurmurHash3_x86_32(c.c_str(), static_cast<int>(c.length()), seed, &seed);
+ MurmurHash3_x86_32(a.c_str(), static_cast<unsigned int>(a.length()), seed, &seed);
+ MurmurHash3_x86_32(b.c_str(), static_cast<unsigned int>(b.length()), seed, &seed);
+ MurmurHash3_x86_32(c.c_str(), static_cast<unsigned int>(c.length()), seed, &seed);
MurmurHash3_x86_32(&d, sizeof(bool), seed, &seed);
return static_cast<size_t>(seed);
@@ -94,9 +94,9 @@ size_t hash<tuple<string, string, string, int> >::operator()(const tuple<string,
const int d = get<3>(t);
uint32_t seed = static_cast<uint32_t>(SMHASHER_SEED_VALUE);
- MurmurHash3_x86_32(a.c_str(), static_cast<int>(a.length()), seed, &seed);
- MurmurHash3_x86_32(b.c_str(), static_cast<int>(b.length()), seed, &seed);
- MurmurHash3_x86_32(c.c_str(), static_cast<int>(c.length()), seed, &seed);
+ MurmurHash3_x86_32(a.c_str(), static_cast<unsigned int>(a.length()), seed, &seed);
+ MurmurHash3_x86_32(b.c_str(), static_cast<unsigned int>(b.length()), seed, &seed);
+ MurmurHash3_x86_32(c.c_str(), static_cast<unsigned int>(c.length()), seed, &seed);
MurmurHash3_x86_32(&d, sizeof(d), seed, &seed);
return static_cast<size_t>(seed);
@@ -109,10 +109,10 @@ size_t hash<tuple<string, string, string, string> >::operator()(const tuple<stri
const string& d = get<3>(t);
uint32_t seed = static_cast<uint32_t>(SMHASHER_SEED_VALUE);
- MurmurHash3_x86_32(a.c_str(), static_cast<int>(a.length()), seed, &seed);
- MurmurHash3_x86_32(b.c_str(), static_cast<int>(b.length()), seed, &seed);
- MurmurHash3_x86_32(c.c_str(), static_cast<int>(c.length()), seed, &seed);
- MurmurHash3_x86_32(d.c_str(), static_cast<int>(d.length()), seed, &seed);
+ MurmurHash3_x86_32(a.c_str(), static_cast<unsigned int>(a.length()), seed, &seed);
+ MurmurHash3_x86_32(b.c_str(), static_cast<unsigned int>(b.length()), seed, &seed);
+ MurmurHash3_x86_32(c.c_str(), static_cast<unsigned int>(c.length()), seed, &seed);
+ MurmurHash3_x86_32(d.c_str(), static_cast<unsigned int>(d.length()), seed, &seed);
return static_cast<size_t>(seed);
}
diff --git a/src/CommonAPI/DBus/DBusInstanceAvailabilityStatusChangedEvent.cpp b/src/CommonAPI/DBus/DBusInstanceAvailabilityStatusChangedEvent.cpp
index 93cd84b..a8d538d 100644
--- a/src/CommonAPI/DBus/DBusInstanceAvailabilityStatusChangedEvent.cpp
+++ b/src/CommonAPI/DBus/DBusInstanceAvailabilityStatusChangedEvent.cpp
@@ -10,10 +10,24 @@
namespace CommonAPI {
namespace DBus {
+DBusInstanceAvailabilityStatusChangedEvent::SignalHandler::SignalHandler(DBusInstanceAvailabilityStatusChangedEvent* _instanceAvblStatusEvent) :
+ instanceAvblStatusEvent_(_instanceAvblStatusEvent) {
+
+}
+
+void DBusInstanceAvailabilityStatusChangedEvent::SignalHandler::onSignalDBusMessage(const DBusMessage& dbusMessage) {
+ if (dbusMessage.hasMemberName("InterfacesAdded")) {
+ instanceAvblStatusEvent_->onInterfacesAddedSignal(dbusMessage);
+ } else if (dbusMessage.hasMemberName("InterfacesRemoved")) {
+ instanceAvblStatusEvent_->onInterfacesRemovedSignal(dbusMessage);
+ }
+}
+
DBusInstanceAvailabilityStatusChangedEvent::DBusInstanceAvailabilityStatusChangedEvent(
DBusProxy &_proxy,
const std::string &_dbusInterfaceName,
const std::string &_capiInterfaceName) :
+ signalHandler_(std::make_shared<SignalHandler>(this)),
proxy_(_proxy),
observedCapiInterfaceName_(_capiInterfaceName),
registry_(DBusServiceRegistry::get(_proxy.getDBusConnection())) {
@@ -25,16 +39,8 @@ DBusInstanceAvailabilityStatusChangedEvent::DBusInstanceAvailabilityStatusChange
}
DBusInstanceAvailabilityStatusChangedEvent::~DBusInstanceAvailabilityStatusChangedEvent() {
- proxy_.removeSignalMemberHandler(interfacesAddedSubscription_, this);
- proxy_.removeSignalMemberHandler(interfacesRemovedSubscription_, this);
-}
-
-void DBusInstanceAvailabilityStatusChangedEvent::onSignalDBusMessage(const DBusMessage& dbusMessage) {
- if (dbusMessage.hasMemberName("InterfacesAdded")) {
- onInterfacesAddedSignal(dbusMessage);
- } else if (dbusMessage.hasMemberName("InterfacesRemoved")) {
- onInterfacesRemovedSignal(dbusMessage);
- }
+ proxy_.removeSignalMemberHandler(interfacesAddedSubscription_, signalHandler_.get());
+ proxy_.removeSignalMemberHandler(interfacesRemovedSubscription_, signalHandler_.get());
}
void DBusInstanceAvailabilityStatusChangedEvent::getAvailableServiceInstances(
@@ -105,12 +111,14 @@ std::future<CallStatus> DBusInstanceAvailabilityStatusChangedEvent::getServiceIn
void DBusInstanceAvailabilityStatusChangedEvent::onFirstListenerAdded(const Listener&) {
+ proxyWeakPtr_ = proxy_.shared_from_this();
+
interfacesAddedSubscription_ = proxy_.addSignalMemberHandler(
proxy_.getDBusAddress().getObjectPath(),
DBusObjectManagerStub::getInterfaceName(),
"InterfacesAdded",
"oa{sa{sv}}",
- this,
+ signalHandler_,
false);
interfacesRemovedSubscription_ = proxy_.addSignalMemberHandler(
@@ -118,7 +126,7 @@ void DBusInstanceAvailabilityStatusChangedEvent::onFirstListenerAdded(const List
DBusObjectManagerStub::getInterfaceName(),
"InterfacesRemoved",
"oas",
- this,
+ signalHandler_,
false);
getAvailableServiceInstancesAsync([&](const CallStatus &_status,
@@ -135,8 +143,8 @@ void DBusInstanceAvailabilityStatusChangedEvent::onFirstListenerAdded(const List
}
void DBusInstanceAvailabilityStatusChangedEvent::onLastListenerRemoved(const Listener&) {
- proxy_.removeSignalMemberHandler(interfacesAddedSubscription_, this);
- proxy_.removeSignalMemberHandler(interfacesRemovedSubscription_, this);
+ proxy_.removeSignalMemberHandler(interfacesAddedSubscription_, signalHandler_.get());
+ proxy_.removeSignalMemberHandler(interfacesRemovedSubscription_, signalHandler_.get());
}
void DBusInstanceAvailabilityStatusChangedEvent::onInterfacesAddedSignal(const DBusMessage &_message) {
@@ -158,7 +166,10 @@ void DBusInstanceAvailabilityStatusChangedEvent::onInterfacesAddedSignal(const D
if (dbusInputStream.hasError()) {
COMMONAPI_ERROR(std::string(__FUNCTION__) + " failed to read interface name");
}
- if(dbusInterfaceName == observedDbusInterfaceName_ && addInterface(dbusObjectPath, dbusInterfaceName)) {
+ if(auto itsProxy = proxyWeakPtr_.lock() &&
+ dbusInterfaceName == observedDbusInterfaceName_ &&
+ addInterface(dbusObjectPath, dbusInterfaceName)) {
+ (void)itsProxy;
notifyInterfaceStatusChanged(dbusObjectPath, dbusInterfaceName, AvailabilityStatus::AVAILABLE);
}
}
@@ -181,7 +192,10 @@ void DBusInstanceAvailabilityStatusChangedEvent::onInterfacesRemovedSignal(const
}
for (const auto& dbusInterfaceName : dbusInterfaceNames) {
- if(dbusInterfaceName == observedDbusInterfaceName_ && removeInterface(dbusObjectPath, dbusInterfaceName)) {
+ if(auto itsProxy = proxyWeakPtr_.lock() &&
+ dbusInterfaceName == observedDbusInterfaceName_ &&
+ removeInterface(dbusObjectPath, dbusInterfaceName)) {
+ (void)itsProxy;
notifyInterfaceStatusChanged(dbusObjectPath, dbusInterfaceName, AvailabilityStatus::NOT_AVAILABLE);
}
}
@@ -198,9 +212,6 @@ void DBusInstanceAvailabilityStatusChangedEvent::notifyInterfaceStatusChanged(
DBusAddressTranslator::get()->translate(itsDBusAddress, itsAddress);
- // ensure, the proxy and the event survives until notification is done
- auto itsProxy = proxy_.shared_from_this();
-
notifyListeners(itsAddress.getAddress(), _availability);
}
diff --git a/src/CommonAPI/DBus/DBusMainLoop.cpp b/src/CommonAPI/DBus/DBusMainLoop.cpp
index b9daea3..5bf27a2 100755
--- a/src/CommonAPI/DBus/DBusMainLoop.cpp
+++ b/src/CommonAPI/DBus/DBusMainLoop.cpp
@@ -220,7 +220,9 @@ void DBusMainLoop::stop() {
void DBusMainLoop::doSingleIteration(const int64_t& timeout) {
{
- std::lock_guard<std::mutex> itsLock(dispatchSourcesMutex_);
+ std::lock_guard<std::mutex> itsDispatchSourcesLock(dispatchSourcesMutex_);
+ std::lock_guard<std::mutex> itsWatchesLock(watchesMutex_);
+
for (auto dispatchSourceIterator = registeredDispatchSources_.begin();
dispatchSourceIterator != registeredDispatchSources_.end();
dispatchSourceIterator++) {
@@ -257,6 +259,43 @@ void DBusMainLoop::doSingleIteration(const int64_t& timeout) {
(dispatchSourceIterator->second)->mutex_->unlock();
}
}
+
+ for (auto watchesIterator = registeredWatches_.begin();
+ watchesIterator != registeredWatches_.end();
+ watchesIterator++) {
+
+ (watchesIterator->second)->mutex_->lock();
+ if ((watchesIterator->second)->deleteObject_) {
+ if (!(watchesIterator->second)->isExecuted_) {
+ (watchesIterator->second)->mutex_->unlock();
+ bool contained = false;
+ for (auto watchesIteratorInner = watchesToDispatch_.begin();
+ watchesIteratorInner != watchesToDispatch_.end(); watchesIteratorInner++) {
+ if (std::get<1>(*watchesIteratorInner)->watch_ == (watchesIterator->second)->watch_) {
+ contained = true;
+ break;
+ }
+ }
+ if (!contained) {
+ delete (watchesIterator->second)->watch_;
+ (watchesIterator->second)->watch_ = NULL;
+ delete (watchesIterator->second)->mutex_;
+ (watchesIterator->second)->mutex_ = NULL;
+ delete watchesIterator->second;
+ watchesIterator = registeredWatches_.erase(watchesIterator);
+ }
+ if (watchesIterator == registeredWatches_.end()) {
+ break;
+ }
+ }
+ else {
+ (watchesIterator->second)->mutex_->unlock();
+ }
+ }
+ else {
+ (watchesIterator->second)->mutex_->unlock();
+ }
+ }
}
{
@@ -299,46 +338,6 @@ void DBusMainLoop::doSingleIteration(const int64_t& timeout) {
}
}
- {
- std::lock_guard<std::mutex> itsLock(watchesMutex_);
- for (auto watchesIterator = registeredWatches_.begin();
- watchesIterator != registeredWatches_.end();
- watchesIterator++) {
-
- (watchesIterator->second)->mutex_->lock();
- if ((watchesIterator->second)->deleteObject_) {
- if (!(watchesIterator->second)->isExecuted_) {
- (watchesIterator->second)->mutex_->unlock();
- bool contained = false;
- for (auto watchesIteratorInner = watchesToDispatch_.begin();
- watchesIteratorInner != watchesToDispatch_.end(); watchesIteratorInner++) {
- if (std::get<1>(*watchesIteratorInner)->watch_ == (watchesIterator->second)->watch_) {
- contained = true;
- break;
- }
- }
- if (!contained) {
- delete (watchesIterator->second)->watch_;
- (watchesIterator->second)->watch_ = NULL;
- delete (watchesIterator->second)->mutex_;
- (watchesIterator->second)->mutex_ = NULL;
- delete watchesIterator->second;
- watchesIterator = registeredWatches_.erase(watchesIterator);
- }
- if (watchesIterator == registeredWatches_.end()) {
- break;
- }
- }
- else {
- (watchesIterator->second)->mutex_->unlock();
- }
- }
- else {
- (watchesIterator->second)->mutex_->unlock();
- }
- }
- }
-
if (prepare(timeout)) {
dispatch();
} else {
@@ -456,7 +455,6 @@ void DBusMainLoop::poll() {
}
bool DBusMainLoop::check() {
- //The first file descriptor always is the loop's wakeup-descriptor (but not for windows anymore). All others need to be linked to a watch.
int managedFileDescriptorOffset = 1;
{
std::lock_guard<std::mutex> itsLock(fileDescriptorsMutex_);
@@ -701,10 +699,10 @@ void DBusMainLoop::unregisterDispatchSource(DispatchSource* dispatchSource) {
void DBusMainLoop::registerWatch(Watch* watch,
const DispatchPriority dispatchPriority) {
- std::lock_guard<std::mutex> itsLock(watchesMutex_);
DBusMainLoopPollFd fdToRegister = watch->getAssociatedFileDescriptor();
-
registerFileDescriptor(fdToRegister);
+
+ std::lock_guard<std::mutex> itsLock(watchesMutex_);
std::mutex* mtx = new std::mutex;
#ifdef WIN32
std::atomic_signal_fence(std::memory_order_acq_rel);
diff --git a/src/CommonAPI/DBus/DBusMainLoopContext.cpp b/src/CommonAPI/DBus/DBusMainLoopContext.cpp
index 428807f..3124027 100644
--- a/src/CommonAPI/DBus/DBusMainLoopContext.cpp
+++ b/src/CommonAPI/DBus/DBusMainLoopContext.cpp
@@ -5,6 +5,7 @@
#ifdef WIN32
#include <WinSock2.h>
+#include <ws2tcpip.h>
#else
#include <poll.h>
#include <unistd.h>
@@ -181,81 +182,127 @@ void DBusWatch::addDependentDispatchSource(DispatchSource* dispatchSource) {
DBusQueueWatch::DBusQueueWatch(std::shared_ptr<DBusConnection> _connection) : pipeValue_(4) {
#ifdef WIN32
- std::string pipeName = "\\\\.\\pipe\\CommonAPI-DBus-";
-
- UUID uuid;
- CHAR* uuidString = NULL;
- UuidCreate(&uuid);
- UuidToString(&uuid, (RPC_CSTR*)&uuidString);
- pipeName += uuidString;
- RpcStringFree((RPC_CSTR*)&uuidString);
-
- HANDLE hPipe = ::CreateNamedPipe(
- pipeName.c_str(),
- PIPE_ACCESS_DUPLEX | FILE_FLAG_OVERLAPPED,
- PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE,
- 1,
- 4096,
- 4096,
- 100,
- nullptr);
-
- if (hPipe == INVALID_HANDLE_VALUE) {
- if (GetLastError() != ERROR_PIPE_BUSY)
- {
- printf("Could not open pipe %d\n", GetLastError());
- }
+ WSADATA wsaData;
+ int iResult;
- // All pipe instances are busy, so wait for sometime.
- else if (!WaitNamedPipe(pipeName.c_str(), NMPWAIT_USE_DEFAULT_WAIT))
- {
- printf("Could not open pipe: wait timed out.\n");
- }
+ SOCKET ListenSocket = INVALID_SOCKET;
+
+ struct addrinfo *result = NULL;
+ struct addrinfo hints;
+
+ // Initialize Winsock
+ iResult = WSAStartup(MAKEWORD(2, 2), &wsaData);
+ if (iResult != 0) {
+ printf("WSAStartup failed with error: %d\n", iResult);
}
- HANDLE hPipe2 = CreateFile(
- pipeName.c_str(), // pipe name
- GENERIC_READ | // read and write access
- GENERIC_WRITE,
- 0, // no sharing
- NULL, // default security attributes
- OPEN_EXISTING, // opens existing pipe
- 0, // default attributes
- NULL); // no template file
-
- if (hPipe2 == INVALID_HANDLE_VALUE) {
- if (GetLastError() != ERROR_PIPE_BUSY)
- {
- printf("Could not open pipe2 %d\n", GetLastError());
- }
+ ZeroMemory(&hints, sizeof(hints));
+ hints.ai_family = AF_INET;
+ hints.ai_socktype = SOCK_STREAM;
+ hints.ai_protocol = IPPROTO_TCP;
+ hints.ai_flags = AI_PASSIVE;
+
+ // Resolve the server address and port
+ iResult = getaddrinfo(NULL, "0", &hints, &result);
+ if (iResult != 0) {
+ printf("getaddrinfo failed with error: %d\n", iResult);
+ WSACleanup();
+ }
- // All pipe instances are busy, so wait for sometime.
- else if (!WaitNamedPipe(pipeName.c_str(), NMPWAIT_USE_DEFAULT_WAIT))
- {
- printf("Could not open pipe2: wait timed out.\n");
- }
+ // Create a SOCKET for connecting to server
+ ListenSocket = socket(result->ai_family, result->ai_socktype, result->ai_protocol);
+ if (ListenSocket == INVALID_SOCKET) {
+ printf("socket failed with error: %ld\n", WSAGetLastError());
+ freeaddrinfo(result);
+ WSACleanup();
}
- pipeFileDescriptors_[0] = (int)hPipe;
- pipeFileDescriptors_[1] = (int)hPipe2;
+ // Setup the TCP listening socket
+ iResult = bind(ListenSocket, result->ai_addr, (int)result->ai_addrlen);
+ if (iResult == SOCKET_ERROR) {
+ printf("bind failed with error: %d\n", WSAGetLastError());
+ freeaddrinfo(result);
+ closesocket(ListenSocket);
+ WSACleanup();
+ }
- wsaEvent_ = ::CreateEventW(nullptr, TRUE, FALSE, nullptr);
+ sockaddr* connected_addr = new sockaddr();
+ USHORT port = 0;
+ int namelength = sizeof(sockaddr);
+ iResult = getsockname(ListenSocket, connected_addr, &namelength);
+ if (iResult == SOCKET_ERROR) {
+ printf("getsockname failed with error: %d\n", WSAGetLastError());
+ } else if (connected_addr->sa_family == AF_INET) {
+ port = ((struct sockaddr_in*)connected_addr)->sin_port;
+ }
+ delete connected_addr;
+
+ freeaddrinfo(result);
- if (wsaEvent_ == WSA_INVALID_EVENT) {
- printf("Invalid Event Created!\n");
+ iResult = listen(ListenSocket, SOMAXCONN);
+ if (iResult == SOCKET_ERROR) {
+ printf("listen failed with error: %d\n", WSAGetLastError());
+ closesocket(ListenSocket);
+ WSACleanup();
}
- ov = { 0 };
- ov.hEvent = wsaEvent_;
+ wsaData;
+ pipeFileDescriptors_[0] = INVALID_SOCKET;
+ struct addrinfo *ptr = NULL;
+
+ // Initialize Winsock
+ iResult = WSAStartup(MAKEWORD(2, 2), &wsaData);
+ if (iResult != 0) {
+ printf("WSAStartup failed with error: %d\n", iResult);
+ }
+
+ ZeroMemory(&hints, sizeof(hints));
+ hints.ai_family = AF_UNSPEC;
+ hints.ai_socktype = SOCK_STREAM;
+ hints.ai_protocol = IPPROTO_TCP;
+
+ // Resolve the server address and port
+ iResult = getaddrinfo("127.0.0.1", std::to_string(ntohs(port)).c_str(), &hints, &result);
+ if (iResult != 0) {
+ printf("getaddrinfo failed with error: %d\n", iResult);
+ WSACleanup();
+ }
- BOOL retVal = ::ConnectNamedPipe(hPipe, &ov);
+ // Attempt to connect to an address until one succeeds
+ for (ptr = result; ptr != NULL; ptr = ptr->ai_next) {
- if (retVal == 0) {
- int error = GetLastError();
+ // Create a SOCKET for connecting to server
+ pipeFileDescriptors_[0] = socket(ptr->ai_family, ptr->ai_socktype,
+ ptr->ai_protocol);
+ if (pipeFileDescriptors_[0] == INVALID_SOCKET) {
+ printf("socket failed with error: %ld\n", WSAGetLastError());
+ WSACleanup();
+ }
- if (error != 535) {
- printf("ERROR: ConnectNamedPipe failed with (%d)\n", error);
+ // Connect to server.
+ iResult = connect(pipeFileDescriptors_[0], ptr->ai_addr, (int)ptr->ai_addrlen);
+ if (iResult == SOCKET_ERROR) {
+ printf("connect failed with error: %ld\n", WSAGetLastError());
+ closesocket(pipeFileDescriptors_[0]);
+ pipeFileDescriptors_[0] = INVALID_SOCKET;
+ continue;
}
+ break;
+ }
+
+ freeaddrinfo(result);
+
+ if (pipeFileDescriptors_[0] == INVALID_SOCKET) {
+ printf("Unable to connect to server!\n");
+ WSACleanup();
+ }
+
+ // Accept a client socket
+ pipeFileDescriptors_[1] = accept(ListenSocket, NULL, NULL);
+ if (pipeFileDescriptors_[1] == INVALID_SOCKET) {
+ printf("accept failed with error: %d\n", WSAGetLastError());
+ closesocket(ListenSocket);
+ WSACleanup();
}
#else
if(pipe2(pipeFileDescriptors_, O_NONBLOCK) == -1) {
@@ -270,23 +317,17 @@ DBusQueueWatch::DBusQueueWatch(std::shared_ptr<DBusConnection> _connection) : pi
DBusQueueWatch::~DBusQueueWatch() {
#ifdef WIN32
- BOOL retVal = DisconnectNamedPipe((HANDLE)pipeFileDescriptors_[0]);
-
- if (!retVal) {
- printf(TEXT("DisconnectNamedPipe failed. GLE=%d\n"), GetLastError());
+ // shutdown the connection since no more data will be sent
+ int iResult = shutdown(pipeFileDescriptors_[0], SD_SEND);
+ if (iResult == SOCKET_ERROR) {
+ printf("shutdown failed with error: %d\n", WSAGetLastError());
+ closesocket(pipeFileDescriptors_[0]);
+ WSACleanup();
}
- retVal = CloseHandle((HANDLE)pipeFileDescriptors_[0]);
-
- if (!retVal) {
- printf(TEXT("CloseHandle failed. GLE=%d\n"), GetLastError());
- }
-
- retVal = CloseHandle((HANDLE)pipeFileDescriptors_[1]);
-
- if (!retVal) {
- printf(TEXT("CloseHandle2 failed. GLE=%d\n"), GetLastError());
- }
+ // cleanup
+ closesocket(pipeFileDescriptors_[0]);
+ WSACleanup();
#else
close(pipeFileDescriptors_[0]);
close(pipeFileDescriptors_[1]);
@@ -337,20 +378,16 @@ void DBusQueueWatch::pushQueue(std::shared_ptr<QueueEntry> _queueEntry) {
queue_.push(_queueEntry);
#ifdef WIN32
- char writeValue[sizeof(pipeValue_)];
- *reinterpret_cast<int*>(writeValue) = pipeValue_;
- DWORD cbWritten;
+ // Send an initial buffer
+ char *sendbuf = "1";
- int fSuccess = WriteFile(
- (HANDLE)pipeFileDescriptors_[1], // pipe handle
- writeValue, // message
- sizeof(pipeValue_), // message length
- &cbWritten, // bytes written
- &ov); // overlapped
+ int iResult = send(pipeFileDescriptors_[1], sendbuf, (int)strlen(sendbuf), 0);
+ if (iResult == SOCKET_ERROR) {
+ int error = WSAGetLastError();
- if (!fSuccess)
- {
- printf(TEXT("WriteFile to pipe failed. GLE=%d\n"), GetLastError());
+ if (error != WSANOTINITIALISED) {
+ printf("send failed with error: %d\n", error);
+ }
}
#else
if(write(pipeFileDescriptors_[1], &pipeValue_, sizeof(pipeValue_)) == -1) {
@@ -363,19 +400,20 @@ void DBusQueueWatch::popQueue() {
std::unique_lock<std::mutex> itsLock(queueMutex_);
#ifdef WIN32
- char readValue[sizeof(pipeValue_)];
- DWORD cbRead;
-
- int fSuccess = ReadFile(
- (HANDLE)pipeFileDescriptors_[0], // pipe handle
- readValue, // buffer to receive reply
- sizeof(pipeValue_), // size of buffer
- &cbRead, // number of bytes read
- &ov); // overlapped
-
- if (!fSuccess)
- {
- printf(TEXT("ReadFile to pipe failed. GLE=%d\n"), GetLastError());
+ // Receive until the peer closes the connection
+ int iResult;
+ char recvbuf[1];
+ int recvbuflen = 1;
+
+ iResult = recv(pipeFileDescriptors_[0], recvbuf, recvbuflen, 0);
+ if (iResult > 0) {
+ //printf("Bytes received from %d: %d\n", wakeFd_.fd, iResult);
+ }
+ else if (iResult == 0) {
+ printf("Connection closed\n");
+ }
+ else {
+ printf("recv failed with error: %d\n", WSAGetLastError());
}
#else
int readValue = 0;
diff --git a/src/CommonAPI/DBus/DBusMessage.cpp b/src/CommonAPI/DBus/DBusMessage.cpp
index 09199dc..927624c 100644
--- a/src/CommonAPI/DBus/DBusMessage.cpp
+++ b/src/CommonAPI/DBus/DBusMessage.cpp
@@ -115,7 +115,7 @@ DBusMessage::createMethodReturn(const std::string &_signature) const {
DBusMessage
DBusMessage::createMethodError(
- const std::string &_code, const std::string &_info) const {
+ const std::string &_code, const std::string &_signature, const std::string &_info) const {
::DBusMessage *methodError
= dbus_message_new_error(message_, _code.c_str(), _info.c_str());
@@ -123,6 +123,8 @@ DBusMessage::createMethodError(
COMMONAPI_ERROR(std::string(__FUNCTION__), " dbus_message_new_error() returned NULL");
}
+ dbus_message_set_signature(methodError, _signature.c_str());
+
return DBusMessage(methodError, false);
}
diff --git a/src/CommonAPI/DBus/DBusProxy.cpp b/src/CommonAPI/DBus/DBusProxy.cpp
index 655fa6c..2d19670 100644
--- a/src/CommonAPI/DBus/DBusProxy.cpp
+++ b/src/CommonAPI/DBus/DBusProxy.cpp
@@ -25,14 +25,8 @@ void DBusProxyStatusEvent::onListenerAdded(const Listener &_listener,
//notify listener about availability status -> push function to mainloop
std::weak_ptr<DBusProxy> itsdbusProxy = dbusProxy_->shared_from_this();
- std::function<void(std::weak_ptr<DBusProxy>, Listener, Subscription)> notifySpecificListenerHandler =
- std::bind(&DBusProxy::notifySpecificListener,
- dbusProxy_,
- std::placeholders::_1,
- std::placeholders::_2,
- std::placeholders::_3);
dbusProxy_->getDBusConnection()->proxyPushFunctionToMainLoop<DBusConnection>(
- notifySpecificListenerHandler,
+ DBusProxy::notifySpecificListener,
itsdbusProxy,
_listener,
_subscription);
@@ -201,10 +195,11 @@ DBusProxy::DBusProxy(const DBusAddress &_dbusAddress,
}
void DBusProxy::init() {
- selfReference_ = shared_from_this();
+ std::weak_ptr<DBusProxy> itsProxy = shared_from_this();
dbusServiceRegistrySubscription_ = dbusServiceRegistry_->subscribeAvailabilityListener(
getAddress().getAddress(),
- std::bind(&DBusProxy::onDBusServiceInstanceStatus, this, std::placeholders::_1));
+ std::bind(&DBusProxy::onDBusServiceInstanceStatus, this, std::placeholders::_1, std::placeholders::_2),
+ itsProxy);
}
DBusProxy::~DBusProxy() {
@@ -300,42 +295,44 @@ InterfaceVersionAttribute& DBusProxy::getInterfaceVersionAttribute() {
void DBusProxy::signalMemberCallback(const CallStatus _status,
const DBusMessage& dbusMessage,
- DBusProxyConnection::DBusSignalHandler *_handler,
+ std::weak_ptr<DBusProxyConnection::DBusSignalHandler> _handler,
const uint32_t _tag) {
(void)_status;
(void)_tag;
- _handler->onSignalDBusMessage(dbusMessage);
+ if(auto itsHandler = _handler.lock())
+ itsHandler->onSignalDBusMessage(dbusMessage);
}
void DBusProxy::signalInitialValueCallback(const CallStatus _status,
const DBusMessage &_message,
- DBusProxyConnection::DBusSignalHandler *_handler,
+ std::weak_ptr<DBusProxyConnection::DBusSignalHandler> _handler,
const uint32_t _tag) {
if (_status != CallStatus::SUCCESS) {
COMMONAPI_ERROR("Error when receiving initial value of an attribute");
} else {
- _handler->onInitialValueSignalDBusMessage(_message, _tag);
+ if(auto itsHandler = _handler.lock())
+ itsHandler->onInitialValueSignalDBusMessage(_message, _tag);
}
}
void DBusProxy::notifySpecificListener(std::weak_ptr<DBusProxy> _dbusProxy,
const ProxyStatusEvent::Listener &_listener,
const ProxyStatusEvent::Subscription _subscription) {
- if(_dbusProxy.lock()) {
- std::lock_guard<std::recursive_mutex> listenersLock(dbusProxyStatusEvent_.listenersMutex_);
+ if(auto itsDbusProxy = _dbusProxy.lock()) {
+ std::lock_guard<std::recursive_mutex> listenersLock(itsDbusProxy->dbusProxyStatusEvent_.listenersMutex_);
- AvailabilityStatus itsStatus = availabilityStatus_;
+ AvailabilityStatus itsStatus = itsDbusProxy->availabilityStatus_;
if (itsStatus != AvailabilityStatus::UNKNOWN)
- dbusProxyStatusEvent_.notifySpecificListener(_subscription, itsStatus);
+ itsDbusProxy->dbusProxyStatusEvent_.notifySpecificListener(_subscription, itsStatus);
//add listener to list so that it can be notified about a change of availability
- dbusProxyStatusEvent_.listeners_.push_back(std::make_pair(_subscription, _listener));
+ itsDbusProxy->dbusProxyStatusEvent_.listeners_.push_back(std::make_pair(_subscription, _listener));
}
}
-void DBusProxy::onDBusServiceInstanceStatus(const AvailabilityStatus& availabilityStatus) {
- //ensure, proxy survives until notification is done
- auto itsSelf = selfReference_.lock();
+void DBusProxy::onDBusServiceInstanceStatus(std::shared_ptr<DBusProxy> _proxy,
+ const AvailabilityStatus& availabilityStatus) {
+ (void)_proxy;
if (availabilityStatus != availabilityStatus_) {
availabilityMutex_.lock();
availabilityStatus_ = availabilityStatus;
@@ -402,13 +399,14 @@ void DBusProxy::onDBusServiceInstanceStatus(const AvailabilityStatus& availabili
signalMemberHandlerIterator != signalMemberHandlerQueue_.end();
signalMemberHandlerIterator++) {
- if (std::get<7>(*signalMemberHandlerIterator)) {
+ auto itsHandler = std::get<5>(*signalMemberHandlerIterator).lock();
+ if (itsHandler && std::get<7>(*signalMemberHandlerIterator)) {
DBusProxyConnection::DBusSignalHandlerToken signalHandlerToken (
std::get<0>(*signalMemberHandlerIterator),
std::get<1>(*signalMemberHandlerIterator),
std::get<2>(*signalMemberHandlerIterator),
std::get<3>(*signalMemberHandlerIterator));
- connection_->removeSignalMemberHandler(signalHandlerToken, std::get<5>(*signalMemberHandlerIterator));
+ connection_->removeSignalMemberHandler(signalHandlerToken, itsHandler.get());
std::get<7>(*signalMemberHandlerIterator) = false;
}
}
@@ -420,7 +418,8 @@ void DBusProxy::onDBusServiceInstanceStatus(const AvailabilityStatus& availabili
}
void DBusProxy::insertSelectiveSubscription(const std::string& interfaceMemberName,
- DBusProxyConnection::DBusSignalHandler* dbusSignalHandler, uint32_t tag,
+ std::weak_ptr<DBusProxyConnection::DBusSignalHandler> dbusSignalHandler,
+ uint32_t tag,
std::string interfaceMemberSignature) {
std::lock_guard < std::mutex > queueLock(selectiveBroadcastHandlersMutex_);
selectiveBroadcastHandlers[interfaceMemberName] = std::make_tuple(
@@ -432,7 +431,7 @@ void DBusProxy::subscribeForSelectiveBroadcastOnConnection(
const std::string& interfaceName,
const std::string& interfaceMemberName,
const std::string& interfaceMemberSignature,
- DBusProxyConnection::DBusSignalHandler* dbusSignalHandler,
+ std::weak_ptr<DBusProxyConnection::DBusSignalHandler> dbusSignalHandler,
uint32_t tag) {
getDBusConnection()->subscribeForSelectiveBroadcast(
@@ -464,7 +463,7 @@ DBusProxyConnection::DBusSignalHandlerToken DBusProxy::addSignalMemberHandler(
const std::string& interfaceName,
const std::string& signalName,
const std::string& signalSignature,
- DBusProxyConnection::DBusSignalHandler* dbusSignalHandler,
+ std::weak_ptr<DBusProxyConnection::DBusSignalHandler> dbusSignalHandler,
const bool justAddFilter) {
return DBusProxyBase::addSignalMemberHandler(
objectPath,
@@ -481,7 +480,7 @@ DBusProxyConnection::DBusSignalHandlerToken DBusProxy::addSignalMemberHandler(
const std::string &signalName,
const std::string &signalSignature,
const std::string &getMethodName,
- DBusProxyConnection::DBusSignalHandler *dbusSignalHandler,
+ std::weak_ptr<DBusProxyConnection::DBusSignalHandler> dbusSignalHandler,
const bool justAddFilter) {
DBusProxyConnection::DBusSignalHandlerToken signalHandlerToken (
@@ -555,7 +554,7 @@ void DBusProxy::addSignalMemberHandlerToQueue(SignalMemberHandlerTuple& _signalM
bool DBusProxy::removeSignalMemberHandler(
const DBusProxyConnection::DBusSignalHandlerToken &_dbusSignalHandlerToken,
- const DBusProxyConnection::DBusSignalHandler *_dbusSignalHandler) {
+ const DBusProxyConnection::DBusSignalHandler* _dbusSignalHandler) {
{
std::lock_guard < std::mutex > queueLock(signalMemberHandlerQueueMutex_);
@@ -581,7 +580,7 @@ bool DBusProxy::removeSignalMemberHandler(
void DBusProxy::getCurrentValueForSignalListener(
const std::string &getMethodName,
- DBusProxyConnection::DBusSignalHandler *dbusSignalHandler,
+ std::weak_ptr<DBusProxyConnection::DBusSignalHandler> dbusSignalHandler,
const uint32_t subscription) {
availabilityMutex_.lock();
@@ -607,7 +606,7 @@ void DBusProxy::getCurrentValueForSignalListener(
}
void DBusProxy::freeDesktopGetCurrentValueForSignalListener(
- DBusProxyConnection::DBusSignalHandler *dbusSignalHandler,
+ std::weak_ptr<DBusProxyConnection::DBusSignalHandler> dbusSignalHandler,
const uint32_t subscription,
const std::string &interfaceName,
const std::string &propertyName) {
diff --git a/src/CommonAPI/DBus/DBusProxyBase.cpp b/src/CommonAPI/DBus/DBusProxyBase.cpp
index 0b1ebe4..3052f9e 100644
--- a/src/CommonAPI/DBus/DBusProxyBase.cpp
+++ b/src/CommonAPI/DBus/DBusProxyBase.cpp
@@ -40,7 +40,7 @@ DBusProxyConnection::DBusSignalHandlerToken DBusProxyBase::addSignalMemberHandle
const std::string& interfaceName,
const std::string& signalName,
const std::string& signalSignature,
- DBusProxyConnection::DBusSignalHandler* dbusSignalHandler,
+ std::weak_ptr<DBusProxyConnection::DBusSignalHandler> dbusSignalHandler,
const bool justAddFilter) {
return connection_->addSignalMemberHandler(
objectPath,
@@ -57,7 +57,7 @@ DBusProxyConnection::DBusSignalHandlerToken DBusProxyBase::addSignalMemberHandle
const std::string &signalName,
const std::string &signalSignature,
const std::string &getMethodName,
- DBusProxyConnection::DBusSignalHandler *dbusSignalHandler,
+ std::weak_ptr<DBusProxyConnection::DBusSignalHandler> dbusSignalHandler,
const bool justAddFilter) {
(void)getMethodName;
return addSignalMemberHandler(
@@ -69,7 +69,8 @@ DBusProxyConnection::DBusSignalHandlerToken DBusProxyBase::addSignalMemberHandle
justAddFilter);
}
-bool DBusProxyBase::removeSignalMemberHandler(const DBusProxyConnection::DBusSignalHandlerToken& _dbusSignalHandlerToken, const DBusProxyConnection::DBusSignalHandler* _dbusSignalHandler) {
+bool DBusProxyBase::removeSignalMemberHandler(const DBusProxyConnection::DBusSignalHandlerToken& _dbusSignalHandlerToken,
+ const DBusProxyConnection::DBusSignalHandler* _dbusSignalHandler) {
return connection_->removeSignalMemberHandler(_dbusSignalHandlerToken, _dbusSignalHandler);
}
diff --git a/src/CommonAPI/DBus/DBusServiceRegistry.cpp b/src/CommonAPI/DBus/DBusServiceRegistry.cpp
index d345a9d..dc7daa8 100644
--- a/src/CommonAPI/DBus/DBusServiceRegistry.cpp
+++ b/src/CommonAPI/DBus/DBusServiceRegistry.cpp
@@ -17,22 +17,22 @@
namespace CommonAPI {
namespace DBus {
-DBusServiceRegistry::RegistryMap_t DBusServiceRegistry::registries_;
std::mutex DBusServiceRegistry::registriesMutex_;
static CommonAPI::CallInfo serviceRegistryInfo(10000);
std::shared_ptr<DBusServiceRegistry>
DBusServiceRegistry::get(std::shared_ptr<DBusProxyConnection> _connection) {
std::lock_guard<std::mutex> itsGuard(registriesMutex_);
- auto registryIterator = registries_.find(_connection);
- if (registryIterator != registries_.end())
+ auto registries = getRegistryMap();
+ auto registryIterator = registries->find(_connection);
+ if (registryIterator != registries->end())
return registryIterator->second;
std::shared_ptr<DBusServiceRegistry> registry
= std::make_shared<DBusServiceRegistry>(_connection);
if (registry) {
registry->init();
- registries_.insert( { _connection, registry } );
+ registries->insert( { _connection, registry } );
}
return registry;
}
@@ -40,13 +40,15 @@ DBusServiceRegistry::get(std::shared_ptr<DBusProxyConnection> _connection) {
void
DBusServiceRegistry::remove(std::shared_ptr<DBusProxyConnection> _connection) {
std::lock_guard<std::mutex> itsGuard(registriesMutex_);
- registries_.erase(_connection);
+ auto registries = getRegistryMap();
+ registries->erase(_connection);
}
DBusServiceRegistry::DBusServiceRegistry(std::shared_ptr<DBusProxyConnection> dbusProxyConnection) :
dbusDaemonProxy_(std::make_shared<CommonAPI::DBus::DBusDaemonProxy>(dbusProxyConnection)),
initialized_(false),
- notificationThread_() {
+ notificationThread_(),
+ registries_(getRegistryMap()) {
}
DBusServiceRegistry::~DBusServiceRegistry() {
@@ -61,7 +63,9 @@ DBusServiceRegistry::~DBusServiceRegistry() {
auto& dbusServiceListenersRecord = dbusServiceListenersIterator.second;
if (dbusServiceListenersRecord.uniqueBusNameState == DBusRecordState::RESOLVED) {
+ dbusServicesMutex_.lock();
onDBusServiceNotAvailable(dbusServiceListenersRecord);
+ dbusServicesMutex_.unlock();
}
}
@@ -80,6 +84,7 @@ DBusServiceRegistry::~DBusServiceRegistry() {
}
void DBusServiceRegistry::init() {
+ selfReference_ = shared_from_this();
translator_ = DBusAddressTranslator::get();
dbusDaemonProxyNameOwnerChangedEventSubscription_ =
@@ -97,7 +102,9 @@ void DBusServiceRegistry::init() {
DBusServiceRegistry::DBusServiceSubscription
DBusServiceRegistry::subscribeAvailabilityListener(
- const std::string &_address, DBusServiceListener serviceListener) {
+ const std::string &_address,
+ DBusServiceListener serviceListener,
+ std::weak_ptr<DBusProxy> _proxy) {
DBusAddress dbusAddress;
translator_->translate(_address, dbusAddress);
@@ -161,11 +168,13 @@ DBusServiceRegistry::subscribeAvailabilityListener(
// LB TODO: check this as it looks STRANGE!!!
if (availabilityStatus != AvailabilityStatus::UNKNOWN) {
notificationThread_ = std::this_thread::get_id();
- serviceListener(availabilityStatus);
+ if(auto itsProxy = _proxy.lock())
+ serviceListener(itsProxy, availabilityStatus);
notificationThread_ = std::thread::id();
}
dbusInterfaceNameListenersRecord.listenerList.push_front(std::move(serviceListener));
+ dbusInterfaceNameListenersRecord.proxy = _proxy;
dbusInterfaceNameListenersRecord.listenersToRemove.remove(
dbusInterfaceNameListenersRecord.listenerList.begin());
@@ -510,7 +519,7 @@ void DBusServiceRegistry::resolveDBusServiceName(const std::string& dbusServiceN
auto func = std::bind(
&DBusServiceRegistry::onGetNameOwnerCallback,
- this->shared_from_this(),
+ shared_from_this(),
std::placeholders::_1,
std::placeholders::_2,
dbusServiceName);
@@ -611,7 +620,7 @@ DBusServiceRegistry::getDBusObjectPathCacheReference(
auto dbusProxyConnection = dbusDaemonProxy_->getDBusConnection();
const bool isSubscriptionSuccessful = dbusProxyConnection->addObjectManagerSignalMemberHandler(
dbusServiceUniqueName,
- this);
+ selfReference_);
if (!isSubscriptionSuccessful) {
COMMONAPI_ERROR(std::string(__FUNCTION__), " cannot subscribe too ", dbusServiceUniqueName);
}
@@ -682,7 +691,7 @@ bool DBusServiceRegistry::resolveObjectPathWithObjectManager(const std::string&
// get managed objects from root object manager
auto getManagedObjectsCallback = std::bind(
&DBusServiceRegistry::onGetManagedObjectsCallbackResolve,
- this->shared_from_this(),
+ shared_from_this(),
std::placeholders::_1,
std::placeholders::_2,
dbusServiceUniqueName,
@@ -788,16 +797,37 @@ void DBusServiceRegistry::onGetManagedObjectsCallbackResolve(const CallStatus& c
}
if(!objectPathFound) {
- // object path is managed. Try to resolve object path with the help of the manager
- auto getManagedObjectsCallback = std::bind(
- &DBusServiceRegistry::onGetManagedObjectsCallbackResolve,
- this->shared_from_this(),
- std::placeholders::_1,
- std::placeholders::_2,
- dbusServiceUniqueName,
- dbusObjectPath);
+ // check if the main part of the object path is in the list.
+ // if it is, the object path could be managed.
+ // else, it maybe existed a while back but is now gone, in which case just ignore.
+
std::string objectPathManager = dbusObjectPath.substr(0, dbusObjectPath.find_last_of("\\/"));
- getManagedObjectsAsync(dbusServiceUniqueName, objectPathManager, getManagedObjectsCallback);
+ for(auto objectPathDict : availableServiceInstances)
+ {
+
+ std::string objectPath = objectPathDict.first;
+
+ if (dbusObjectPath.substr(0, objectPath.size()) != objectPath)
+ continue;
+
+ // also check that the next character in dbusObject path is a slash or a backslash,
+ // so that we can make sure that we have compared against a full path element
+ auto delimiter = dbusObjectPath.at(objectPath.size());
+ if (delimiter != '\\' && delimiter != '/')
+ continue;
+
+ // object path is managed. Try to resolve object path with the help of the manager
+ auto getManagedObjectsCallback = std::bind(
+ &DBusServiceRegistry::onGetManagedObjectsCallbackResolve,
+ shared_from_this(),
+ std::placeholders::_1,
+ std::placeholders::_2,
+ dbusServiceUniqueName,
+ dbusObjectPath);
+ getManagedObjectsAsync(dbusServiceUniqueName, objectPathManager, getManagedObjectsCallback);
+
+ }
+
}
} else {
COMMONAPI_ERROR("There is no Object Manager that manages " + dbusObjectPath + ". Resolving failed!");
@@ -1070,7 +1100,8 @@ void DBusServiceRegistry::notifyDBusInterfaceNameListeners(DBusInterfaceNameList
dbusInterfaceNameListenersRecord.listenersToRemove.remove(dbusServiceListenerIterator);
dbusServiceListenerIterator = dbusInterfaceNameListenersRecord.listenerList.erase(dbusServiceListenerIterator);
} else {
- (*dbusServiceListenerIterator)(availabilityStatus);
+ if(auto itsProxy = dbusInterfaceNameListenersRecord.proxy.lock())
+ (*dbusServiceListenerIterator)(itsProxy, availabilityStatus);
++dbusServiceListenerIterator;
}
}
diff --git a/src/dbus-patches/capi-dbus-send-with-reply-and-block-delete-reply-on-error.patch b/src/dbus-patches/capi-dbus-send-with-reply-and-block-delete-reply-on-error.patch
new file mode 100644
index 0000000..51f3953
--- /dev/null
+++ b/src/dbus-patches/capi-dbus-send-with-reply-and-block-delete-reply-on-error.patch
@@ -0,0 +1,26 @@
+diff --git a/dbus/dbus-connection.c b/dbus/dbus-connection.c
+index 5962e77..4a4ee9b 100644
+--- a/dbus/dbus-connection.c
++++ b/dbus/dbus-connection.c
+@@ -3709,13 +3709,9 @@ dbus_connection_send_with_reply_and_block (DBusConnection *connection,
+ */
+ _dbus_assert (reply != NULL);
+
+- if (dbus_set_error_from_message (error, reply))
+- {
+- dbus_message_unref (reply);
+- return NULL;
+- }
+- else
+- return reply;
++ dbus_set_error_from_message (error, reply);
++
++ return reply;
+ }
+
+ /**
+@@ -6447,3 +6443,4 @@ _dbus_connection_get_address (DBusConnection *connection)
+ #endif
+
+ /** @} */
++
diff --git a/src/murmurhash/MurmurHash3.cpp b/src/murmurhash/MurmurHash3.cpp
index 2e06040..86ca147 100644
--- a/src/murmurhash/MurmurHash3.cpp
+++ b/src/murmurhash/MurmurHash3.cpp
@@ -91,7 +91,7 @@ inline uint64_t fmix ( uint64_t k )
//-----------------------------------------------------------------------------
-void MurmurHash3_x86_32 ( const void * key, int len,
+void MurmurHash3_x86_32 ( const void * key, unsigned int len,
uint32_t seed, void * out )
{
const uint8_t * data = (const uint8_t*)key;
@@ -129,8 +129,8 @@ void MurmurHash3_x86_32 ( const void * key, int len,
switch(len & 3)
{
- case 3: k1 ^= tail[2] << 16;
- case 2: k1 ^= tail[1] << 8;
+ case 3: k1 ^= uint32_t(tail[2] << 16);
+ case 2: k1 ^= uint32_t(tail[1] << 8);
case 1: k1 ^= tail[0];
k1 *= c1; k1 = ROTL32(k1,15); k1 *= c2; h1 ^= k1;
};
@@ -147,7 +147,7 @@ void MurmurHash3_x86_32 ( const void * key, int len,
//-----------------------------------------------------------------------------
-void MurmurHash3_x86_128 ( const void * key, const int len,
+void MurmurHash3_x86_128 ( const void * key, const unsigned int len,
uint32_t seed, void * out )
{
const uint8_t * data = (const uint8_t*)key;
@@ -204,27 +204,27 @@ void MurmurHash3_x86_128 ( const void * key, const int len,
switch(len & 15)
{
- case 15: k4 ^= tail[14] << 16;
- case 14: k4 ^= tail[13] << 8;
- case 13: k4 ^= tail[12] << 0;
+ case 15: k4 ^= uint32_t(tail[14] << 16);
+ case 14: k4 ^= uint32_t(tail[13] << 8);
+ case 13: k4 ^= tail[12];
k4 *= c4; k4 = ROTL32(k4,18); k4 *= c1; h4 ^= k4;
- case 12: k3 ^= tail[11] << 24;
- case 11: k3 ^= tail[10] << 16;
- case 10: k3 ^= tail[ 9] << 8;
- case 9: k3 ^= tail[ 8] << 0;
+ case 12: k3 ^= uint32_t(tail[11] << 24);
+ case 11: k3 ^= uint32_t(tail[10] << 16);
+ case 10: k3 ^= uint32_t(tail[ 9] << 8);
+ case 9: k3 ^= tail[ 8];
k3 *= c3; k3 = ROTL32(k3,17); k3 *= c4; h3 ^= k3;
- case 8: k2 ^= tail[ 7] << 24;
- case 7: k2 ^= tail[ 6] << 16;
- case 6: k2 ^= tail[ 5] << 8;
- case 5: k2 ^= tail[ 4] << 0;
+ case 8: k2 ^= uint32_t(tail[ 7] << 24);
+ case 7: k2 ^= uint32_t(tail[ 6] << 16);
+ case 6: k2 ^= uint32_t(tail[ 5] << 8);
+ case 5: k2 ^= tail[ 4];
k2 *= c2; k2 = ROTL32(k2,16); k2 *= c3; h2 ^= k2;
- case 4: k1 ^= tail[ 3] << 24;
- case 3: k1 ^= tail[ 2] << 16;
- case 2: k1 ^= tail[ 1] << 8;
- case 1: k1 ^= tail[ 0] << 0;
+ case 4: k1 ^= uint32_t(tail[ 3] << 24);
+ case 3: k1 ^= uint32_t(tail[ 2] << 16);
+ case 2: k1 ^= uint32_t(tail[ 1] << 8);
+ case 1: k1 ^= tail[ 0];
k1 *= c1; k1 = ROTL32(k1,15); k1 *= c2; h1 ^= k1;
};
@@ -252,7 +252,7 @@ void MurmurHash3_x86_128 ( const void * key, const int len,
//-----------------------------------------------------------------------------
-void MurmurHash3_x64_128 ( const void * key, const int len,
+void MurmurHash3_x64_128 ( const void * key, const unsigned int len,
const uint32_t seed, void * out )
{
const uint8_t * data = (const uint8_t*)key;
diff --git a/src/pugixml/pugixml.cpp b/src/pugixml/pugixml.cpp
index 9778df1..a97e065 100644
--- a/src/pugixml/pugixml.cpp
+++ b/src/pugixml/pugixml.cpp
@@ -879,21 +879,21 @@ PUGI__NS_BEGIN
// 110xxxxx -> U+0080..U+07FF
else if (static_cast<unsigned int>(lead - 0xC0) < 0x20 && size >= 2 && (data[1] & 0xc0) == 0x80)
{
- result = Traits::low(result, ((lead & ~0xC0) << 6) | (data[1] & utf8_byte_mask));
+ result = Traits::low(result, unsigned((lead & ~0xC0) << 6) | (data[1] & utf8_byte_mask));
data += 2;
size -= 2;
}
// 1110xxxx -> U+0800-U+FFFF
else if (static_cast<unsigned int>(lead - 0xE0) < 0x10 && size >= 3 && (data[1] & 0xc0) == 0x80 && (data[2] & 0xc0) == 0x80)
{
- result = Traits::low(result, ((lead & ~0xE0) << 12) | ((data[1] & utf8_byte_mask) << 6) | (data[2] & utf8_byte_mask));
+ result = Traits::low(result, unsigned((lead & ~0xE0) << 12) | unsigned((data[1] & utf8_byte_mask) << 6) | (data[2] & utf8_byte_mask));
data += 3;
size -= 3;
}
// 11110xxx -> U+10000..U+10FFFF
else if (static_cast<unsigned int>(lead - 0xF0) < 0x08 && size >= 4 && (data[1] & 0xc0) == 0x80 && (data[2] & 0xc0) == 0x80 && (data[3] & 0xc0) == 0x80)
{
- result = Traits::high(result, ((lead & ~0xF0) << 18) | ((data[1] & utf8_byte_mask) << 12) | ((data[2] & utf8_byte_mask) << 6) | (data[3] & utf8_byte_mask));
+ result = Traits::high(result, unsigned((lead & ~0xF0) << 18) | unsigned((data[1] & utf8_byte_mask) << 12) | unsigned((data[2] & utf8_byte_mask) << 6) | (data[3] & utf8_byte_mask));
data += 4;
size -= 4;
}
@@ -935,7 +935,7 @@ PUGI__NS_BEGIN
if (static_cast<unsigned int>(next - 0xDC00) < 0x400)
{
- result = Traits::high(result, 0x10000 + ((lead & 0x3ff) << 10) + (next & 0x3ff));
+ result = Traits::high(result, 0x10000 + unsigned((lead & 0x3ff) << 10) + (next & 0x3ff));
data += 2;
}
else
@@ -1328,7 +1328,7 @@ PUGI__NS_BEGIN
// source encoding is latin1
if (encoding == encoding_latin1) return convert_buffer_latin1(out_buffer, out_length, contents, size);
- assert(!"Invalid encoding");
+ assert(0 && "Invalid encoding");
return false;
}
#else
@@ -1446,7 +1446,7 @@ PUGI__NS_BEGIN
// source encoding is latin1
if (encoding == encoding_latin1) return convert_buffer_latin1(out_buffer, out_length, contents, size, is_mutable);
- assert(!"Invalid encoding");
+ assert(false && "Invalid encoding");
return false;
}
#endif
@@ -1588,7 +1588,7 @@ PUGI__NS_BEGIN
{
// Move [old_gap_end, new_gap_start) to [old_gap_start, ...)
assert(s >= end);
- memmove(end - size, end, reinterpret_cast<char*>(s) - reinterpret_cast<char*>(end));
+ memmove(end - size, end, size_t(reinterpret_cast<char*>(s) - reinterpret_cast<char*>(end)));
}
s += count; // end of current gap
@@ -1605,7 +1605,7 @@ PUGI__NS_BEGIN
{
// Move [old_gap_end, current_pos) to [old_gap_start, ...)
assert(s >= end);
- memmove(end - size, end, reinterpret_cast<char*>(s) - reinterpret_cast<char*>(end));
+ memmove(end - size, end, size_t(reinterpret_cast<char*>(s) - reinterpret_cast<char*>(end)));
return s - size;
}
@@ -1634,9 +1634,9 @@ PUGI__NS_BEGIN
for (;;)
{
if (static_cast<unsigned int>(ch - '0') <= 9)
- ucsc = 16 * ucsc + (ch - '0');
+ ucsc = 16 * ucsc + (unsigned int)(ch - '0');
else if (static_cast<unsigned int>((ch | ' ') - 'a') <= 5)
- ucsc = 16 * ucsc + ((ch | ' ') - 'a' + 10);
+ ucsc = 16 * ucsc + ((unsigned int)(ch | ' ') - 'a' + 10);
else if (ch == ';')
break;
else // cancel
@@ -1656,7 +1656,7 @@ PUGI__NS_BEGIN
for (;;)
{
if (static_cast<unsigned int>(ch - '0') <= 9)
- ucsc = 10 * ucsc + (ch - '0');
+ ucsc = 10 * ucsc + (unsigned int)(ch - '0');
else if (ch == ';')
break;
else // cancel
@@ -1674,7 +1674,7 @@ PUGI__NS_BEGIN
s = reinterpret_cast<char_t*>(utf8_writer::any(reinterpret_cast<uint8_t*>(s), ucsc));
#endif
- g.push(s, stre - s);
+ g.push(s, size_t(stre - s));
return stre;
}
@@ -1689,7 +1689,7 @@ PUGI__NS_BEGIN
*s++ = '&';
++stre;
- g.push(s, stre - s);
+ g.push(s, size_t(stre - s));
return stre;
}
}
@@ -1700,7 +1700,7 @@ PUGI__NS_BEGIN
*s++ = '\'';
++stre;
- g.push(s, stre - s);
+ g.push(s, size_t(stre - s));
return stre;
}
}
@@ -1714,7 +1714,7 @@ PUGI__NS_BEGIN
*s++ = '>';
++stre;
- g.push(s, stre - s);
+ g.push(s, size_t(stre - s));
return stre;
}
break;
@@ -1727,7 +1727,7 @@ PUGI__NS_BEGIN
*s++ = '<';
++stre;
- g.push(s, stre - s);
+ g.push(s, size_t(stre - s));
return stre;
}
break;
@@ -1740,7 +1740,7 @@ PUGI__NS_BEGIN
*s++ = '"';
++stre;
- g.push(s, stre - s);
+ g.push(s, size_t(stre - s));
return stre;
}
break;
@@ -1879,7 +1879,7 @@ PUGI__NS_BEGIN
do ++str;
while (PUGI__IS_CHARTYPE(*str, ct_space));
- g.push(s, str - s);
+ g.push(s, size_t(str - s));
}
while (true)
@@ -1904,7 +1904,7 @@ PUGI__NS_BEGIN
char_t* str = s + 1;
while (PUGI__IS_CHARTYPE(*str, ct_space)) ++str;
- g.push(s, str - s);
+ g.push(s, size_t(str - s));
}
}
else if (opt_escape::value && *s == '&')
@@ -2643,7 +2643,7 @@ PUGI__NS_BEGIN
if (result && endch == '<')
{
// there's no possible well-formed document with < at the end
- return make_parse_result(status_unrecognized_tag, length);
+ return make_parse_result(status_unrecognized_tag, (ptrdiff_t)length);
}
return result;
@@ -2747,7 +2747,7 @@ PUGI__NS_BEGIN
return static_cast<size_t>(end - dest);
}
- assert(!"Invalid encoding");
+ assert(0 && "Invalid encoding");
return 0;
}
#else
@@ -2807,7 +2807,7 @@ PUGI__NS_BEGIN
return static_cast<size_t>(end - dest);
}
- assert(!"Invalid encoding");
+ assert(0 && "Invalid encoding");
return 0;
}
#endif
@@ -3203,7 +3203,7 @@ PUGI__NS_BEGIN
break;
default:
- assert(!"Invalid node type");
+ assert(0 && "Invalid node type");
}
}
@@ -3278,7 +3278,7 @@ PUGI__NS_BEGIN
}
default:
- assert(!"Invalid node type");
+ assert(0 && "Invalid node type");
}
}
@@ -5609,7 +5609,7 @@ PUGI__NS_BEGIN
else
{
// median of nine
- size_t step = (last - first + 1) / 8;
+ size_t step = size_t(last - first + 1) / 8;
median3(first, first + step, first + 2 * step, pred);
median3(middle - step, middle, middle + step, pred);
@@ -6729,7 +6729,7 @@ PUGI__NS_BEGIN
break;
default:
- assert(!"Invalid variable type");
+ assert(0 && "Invalid variable type");
}
}
@@ -6794,7 +6794,7 @@ PUGI__NS_BEGIN
return *min_element(begin, end, document_order_comparator());
default:
- assert(!"Invalid node set type");
+ assert(0 && "Invalid node set type");
return xpath_node();
}
}
@@ -7492,7 +7492,7 @@ PUGI__NS_BEGIN
}
}
- assert(!"Wrong types");
+ assert(0 && "Wrong types");
return false;
}
@@ -7562,7 +7562,7 @@ PUGI__NS_BEGIN
}
else
{
- assert(!"Wrong types");
+ assert(0 && "Wrong types");
return false;
}
}
@@ -7679,7 +7679,7 @@ PUGI__NS_BEGIN
break;
default:
- assert(!"Unknown axis");
+ assert(0 && "Unknown axis");
}
}
@@ -7849,7 +7849,7 @@ PUGI__NS_BEGIN
}
default:
- assert(!"Unimplemented axis");
+ assert(0 && "Unimplemented axis");
}
}
@@ -7925,7 +7925,7 @@ PUGI__NS_BEGIN
}
default:
- assert(!"Unimplemented axis");
+ assert(0 && "Unimplemented axis");
}
}
@@ -8142,7 +8142,7 @@ PUGI__NS_BEGIN
}
default:
- assert(!"Wrong expression for return type boolean");
+ assert(0 && "Wrong expression for return type boolean");
return false;
}
}
@@ -8278,7 +8278,7 @@ PUGI__NS_BEGIN
}
default:
- assert(!"Wrong expression for return type number");
+ assert(0 && "Wrong expression for return type number");
return 0;
}
@@ -8546,7 +8546,7 @@ PUGI__NS_BEGIN
}
default:
- assert(!"Wrong expression for return type string");
+ assert(0 && "Wrong expression for return type string");
return xpath_string();
}
}
@@ -8636,7 +8636,7 @@ PUGI__NS_BEGIN
return step_do(c, stack, axis_to_type<axis_self>());
default:
- assert(!"Unknown axis");
+ assert(0 && "Unknown axis");
return xpath_node_set_raw();
}
}
@@ -8675,7 +8675,7 @@ PUGI__NS_BEGIN
}
default:
- assert(!"Wrong expression for return type node set");
+ assert(0 && "Wrong expression for return type node set");
return xpath_node_set_raw();
}
}
@@ -9784,7 +9784,7 @@ namespace pugi
PUGI__FN size_t xpath_node_set::size() const
{
- return _end - _begin;
+ return size_t(_end - _begin);
}
PUGI__FN bool xpath_node_set::empty() const
@@ -9853,7 +9853,7 @@ namespace pugi
return static_cast<const impl::xpath_variable_boolean*>(this)->name;
default:
- assert(!"Invalid variable type");
+ assert(0 && "Invalid variable type");
return 0;
}
}