summaryrefslogtreecommitdiff
path: root/include
diff options
context:
space:
mode:
Diffstat (limited to 'include')
-rw-r--r--include/CommonAPI/DBus/DBusAttribute.hpp13
-rw-r--r--include/CommonAPI/DBus/DBusClientId.hpp2
-rw-r--r--include/CommonAPI/DBus/DBusConfig.hpp3
-rw-r--r--include/CommonAPI/DBus/DBusConnection.hpp67
-rw-r--r--include/CommonAPI/DBus/DBusDaemonProxy.hpp81
-rw-r--r--include/CommonAPI/DBus/DBusFactory.hpp19
-rw-r--r--include/CommonAPI/DBus/DBusFreedesktopPropertiesStub.hpp2
-rw-r--r--include/CommonAPI/DBus/DBusFreedesktopStubAdapterHelper.hpp50
-rw-r--r--include/CommonAPI/DBus/DBusInputStream.hpp110
-rw-r--r--include/CommonAPI/DBus/DBusInstanceAvailabilityStatusChangedEvent.hpp16
-rwxr-xr-xinclude/CommonAPI/DBus/DBusMainLoop.hpp8
-rw-r--r--include/CommonAPI/DBus/DBusMainLoopContext.hpp93
-rw-r--r--include/CommonAPI/DBus/DBusMessage.hpp2
-rw-r--r--include/CommonAPI/DBus/DBusObjectManager.hpp3
-rw-r--r--include/CommonAPI/DBus/DBusObjectManagerStub.hpp2
-rw-r--r--include/CommonAPI/DBus/DBusOutputStream.hpp15
-rw-r--r--include/CommonAPI/DBus/DBusProxy.hpp35
-rw-r--r--include/CommonAPI/DBus/DBusProxyAsyncCallbackHandler.hpp31
-rw-r--r--include/CommonAPI/DBus/DBusProxyAsyncSignalMemberCallbackHandler.hpp34
-rw-r--r--include/CommonAPI/DBus/DBusProxyBase.hpp7
-rw-r--r--include/CommonAPI/DBus/DBusProxyConnection.hpp27
-rw-r--r--include/CommonAPI/DBus/DBusProxyHelper.hpp103
-rw-r--r--include/CommonAPI/DBus/DBusProxyManager.hpp2
-rw-r--r--include/CommonAPI/DBus/DBusSelectiveEvent.hpp25
-rw-r--r--include/CommonAPI/DBus/DBusServiceRegistry.hpp3
-rw-r--r--include/CommonAPI/DBus/DBusStubAdapter.hpp2
-rw-r--r--include/CommonAPI/DBus/DBusStubAdapterHelper.hpp41
-rw-r--r--include/murmurhash/MurmurHash3.h8
28 files changed, 590 insertions, 214 deletions
diff --git a/include/CommonAPI/DBus/DBusAttribute.hpp b/include/CommonAPI/DBus/DBusAttribute.hpp
index ba3ca77..2fd5bd3 100644
--- a/include/CommonAPI/DBus/DBusAttribute.hpp
+++ b/include/CommonAPI/DBus/DBusAttribute.hpp
@@ -10,7 +10,6 @@
#ifndef COMMONAPI_DBUS_DBUS_ATTRIBUTE_HPP_
#define COMMONAPI_DBUS_DBUS_ATTRIBUTE_HPP_
-#include <cassert>
#include <cstdint>
#include <tuple>
@@ -35,7 +34,9 @@ public:
getMethodName_(getMethodName),
setMethodSignature_(setMethodSignature),
depl_(_depl) {
- assert(getMethodName);
+ if (NULL == getMethodName) {
+ COMMONAPI_ERROR(std::string(__FUNCTION__) + ": getMethodName is NULL");
+ }
}
void getValue(CommonAPI::CallStatus &_status, ValueType &_value, const CommonAPI::CallInfo *_info) const {
@@ -84,8 +85,12 @@ public:
: DBusReadonlyAttribute<AttributeType_, AttributeDepl_>(_proxy, _setMethodSignature, _getMethodName, _depl),
setMethodName_(_setMethodName),
setMethodSignature_(_setMethodSignature) {
- assert(_setMethodName);
- assert(_setMethodSignature);
+ if (NULL == _setMethodName) {
+ COMMONAPI_ERROR(std::string(__FUNCTION__) + ": _setMethodName is NULL");
+ }
+ if (NULL == _setMethodSignature) {
+ COMMONAPI_ERROR(std::string(__FUNCTION__) + ": _setMethodSignature is NULL");
+ }
}
void setValue(const ValueType &_request, CommonAPI::CallStatus &_status, ValueType &_response, const CommonAPI::CallInfo *_info) {
diff --git a/include/CommonAPI/DBus/DBusClientId.hpp b/include/CommonAPI/DBus/DBusClientId.hpp
index 02e369f..982b4dd 100644
--- a/include/CommonAPI/DBus/DBusClientId.hpp
+++ b/include/CommonAPI/DBus/DBusClientId.hpp
@@ -24,7 +24,7 @@ class DBusMessage;
* This class represents the DBus specific implementation of CommonAPI::ClientId.
* It internally uses a string to identify clients. This string is the unique sender id used by dbus.
*/
-class DBusClientId
+class COMMONAPI_EXPORT_CLASS_EXPLICIT DBusClientId
: public CommonAPI::ClientId {
friend struct std::hash<DBusClientId>;
diff --git a/include/CommonAPI/DBus/DBusConfig.hpp b/include/CommonAPI/DBus/DBusConfig.hpp
index dae6b7a..cb07461 100644
--- a/include/CommonAPI/DBus/DBusConfig.hpp
+++ b/include/CommonAPI/DBus/DBusConfig.hpp
@@ -15,8 +15,7 @@
namespace CommonAPI {
namespace DBus {
-static const Timeout_t DEFAULT_SEND_TIMEOUT_MS = 5000;
-static CommonAPI::CallInfo defaultCallInfo(DEFAULT_SEND_TIMEOUT_MS);
+static CommonAPI::CallInfo defaultCallInfo(CommonAPI::DEFAULT_SEND_TIMEOUT_MS);
} // namespace DBus
} // namespace CommonAPI
diff --git a/include/CommonAPI/DBus/DBusConnection.hpp b/include/CommonAPI/DBus/DBusConnection.hpp
index f2fd516..f79dc27 100644
--- a/include/CommonAPI/DBus/DBusConnection.hpp
+++ b/include/CommonAPI/DBus/DBusConnection.hpp
@@ -45,12 +45,14 @@ friend class DBusConnection;
};
struct WatchContext {
- WatchContext(std::weak_ptr<MainLoopContext> mainLoopContext, DispatchSource* dispatchSource) :
- mainLoopContext_(mainLoopContext), dispatchSource_(dispatchSource) {
+ WatchContext(std::weak_ptr<MainLoopContext> mainLoopContext, DispatchSource* dispatchSource,
+ std::weak_ptr<DBusConnection> dbusConnection) :
+ mainLoopContext_(mainLoopContext), dispatchSource_(dispatchSource), dbusConnection_(dbusConnection) {
}
std::weak_ptr<MainLoopContext> mainLoopContext_;
DispatchSource* dispatchSource_;
+ std::weak_ptr<DBusConnection> dbusConnection_;
};
class DBusConnection
@@ -107,13 +109,13 @@ public:
DBusSignalHandler* dbusSignalHandler,
const bool justAddFilter = false);
- COMMONAPI_EXPORT DBusProxyConnection::DBusSignalHandlerToken subscribeForSelectiveBroadcast(bool& subscriptionAccepted,
- const std::string& objectPath,
- const std::string& interfaceName,
- const std::string& interfaceMemberName,
- const std::string& interfaceMemberSignature,
- DBusSignalHandler* dbusSignalHandler,
- DBusProxy* callingProxy);
+ COMMONAPI_EXPORT void subscribeForSelectiveBroadcast(const std::string& objectPath,
+ const std::string& interfaceName,
+ const std::string& interfaceMemberName,
+ const std::string& interfaceMemberSignature,
+ DBusSignalHandler* dbusSignalHandler,
+ DBusProxy* callingProxy,
+ uint32_t tag);
COMMONAPI_EXPORT void unsubscribeFromSelectiveBroadcast(const std::string& eventName,
DBusProxyConnection::DBusSignalHandlerToken subscription,
@@ -136,11 +138,21 @@ public:
COMMONAPI_EXPORT bool isDispatchReady();
COMMONAPI_EXPORT bool singleDispatch();
+ COMMONAPI_EXPORT void dispatchDBusMessageReply(const DBusMessage& _reply,
+ DBusMessageReplyAsyncHandler* _dbusMessageReplyAsyncHandler);
COMMONAPI_EXPORT virtual bool hasDispatchThread();
COMMONAPI_EXPORT virtual const ConnectionId_t& getConnectionId() const;
+ COMMONAPI_EXPORT void incrementConnection();
+ COMMONAPI_EXPORT void decrementConnection();
+
+ COMMONAPI_EXPORT bool setDispatching(bool isDispatching);
+
+ COMMONAPI_EXPORT void pushDBusMessageReply(const DBusMessage& _reply,
+ std::unique_ptr<DBusMessageReplyAsyncHandler> _dbusMessageReplyAsyncHandler);
+
#ifdef COMMONAPI_DBUS_TEST
inline std::weak_ptr<DBusMainloop> getLoop() { return loop_; }
#endif
@@ -149,21 +161,29 @@ public:
typedef std::pair<uint32_t, std::string> DBusSignalMatchRuleMapping;
typedef std::unordered_map<DBusSignalMatchRuleTuple, DBusSignalMatchRuleMapping> DBusSignalMatchRulesMap;
private:
+
+ struct PendingCallNotificationData {
+ PendingCallNotificationData(const DBusConnection* _dbusConnection,
+ DBusMessageReplyAsyncHandler* _replyAsyncHandler) :
+ dbusConnection_(_dbusConnection),
+ replyAsyncHandler_(_replyAsyncHandler) { }
+
+ const DBusConnection* dbusConnection_;
+ DBusMessageReplyAsyncHandler* replyAsyncHandler_;
+ };
+
COMMONAPI_EXPORT void dispatch();
COMMONAPI_EXPORT void suspendDispatching() const;
COMMONAPI_EXPORT void resumeDispatching() const;
std::thread* dispatchThread_;
- bool stopDispatching_;
std::weak_ptr<MainLoopContext> mainLoopContext_;
+ DBusMessageWatch* msgWatch_;
+ DBusMessageDispatchSource* msgDispatchSource_;
DispatchSource* dispatchSource_;
WatchContext* watchContext_;
- mutable std::recursive_mutex sendLock_;
- mutable bool pauseDispatching_;
- mutable std::mutex dispatchSuspendLock_;
-
COMMONAPI_EXPORT void addLibdbusSignalMatchRule(const std::string& objectPath,
const std::string& interfaceName,
const std::string& interfaceMemberName,
@@ -179,9 +199,11 @@ public:
COMMONAPI_EXPORT void initLibdbusObjectPathHandlerAfterConnect();
::DBusHandlerResult onLibdbusObjectPathMessage(::DBusMessage* libdbusMessage);
- COMMONAPI_EXPORT static DBusMessage convertToDBusMessage(::DBusPendingCall* _libdbusPendingCall,
- CallStatus& _callStatus);
+ COMMONAPI_EXPORT static DBusMessage convertToDBusMessage(::DBusPendingCall* _libdbusPendingCall);
COMMONAPI_EXPORT static void onLibdbusPendingCallNotifyThunk(::DBusPendingCall* libdbusPendingCall, void* userData);
+ void onLibdbusPendingCall(::DBusPendingCall* _libdbusPendingCall,
+ const DBusMessage& _reply,
+ DBusMessageReplyAsyncHandler* _dbusMessageReplyAsyncHandler) const;
COMMONAPI_EXPORT static void onLibdbusDataCleanup(void* userData);
COMMONAPI_EXPORT static ::DBusHandlerResult onLibdbusObjectPathMessageThunk(::DBusConnection* libdbusConnection,
@@ -205,7 +227,8 @@ public:
COMMONAPI_EXPORT void enforceAsynchronousTimeouts() const;
COMMONAPI_EXPORT static const DBusObjectPathVTable* getDBusObjectPathVTable();
- COMMONAPI_EXPORT bool sendPendingSelectiveSubscription(DBusProxy* proxy, std::string methodName);
+ COMMONAPI_EXPORT void sendPendingSelectiveSubscription(DBusProxy* proxy, std::string methodName,
+ DBusSignalHandler* dbusSignalHandler, uint32_t tag);
::DBusConnection* connection_;
mutable std::mutex connectionGuard_;
@@ -284,6 +307,16 @@ public:
mutable std::set<DBusMessageReplyAsyncHandler*> timeoutInfiniteAsyncHandlers_;
mutable std::mutex timeoutInfiniteAsyncHandlersMutex_;
+ uint32_t activeConnections_;
+ mutable std::mutex activeConnectionsMutex_;
+
+ bool isDisconnecting_;
+ bool isDispatching_;
+ bool isWaitingOnFinishedDispatching_;
+
+ std::set<std::thread::id> dispatchThreads_;
+ std::mutex dispatchMutex_;
+ std::condition_variable dispatchCondition_;
};
diff --git a/include/CommonAPI/DBus/DBusDaemonProxy.hpp b/include/CommonAPI/DBus/DBusDaemonProxy.hpp
index 69541b6..0652654 100644
--- a/include/CommonAPI/DBus/DBusDaemonProxy.hpp
+++ b/include/CommonAPI/DBus/DBusDaemonProxy.hpp
@@ -34,8 +34,14 @@ class StaticInterfaceVersionAttribute: public InterfaceVersionAttribute {
Version version_;
};
+#ifndef DBUS_DAEMON_PROXY_DEFAULT_SEND_TIMEOUT
+#define DBUS_DAEMON_PROXY_DEFAULT_SEND_TIMEOUT 10000
+#endif
+
+static const CommonAPI::CallInfo daemonProxyInfo(DBUS_DAEMON_PROXY_DEFAULT_SEND_TIMEOUT);
-class DBusDaemonProxy : public DBusProxyBase {
+class DBusDaemonProxy : public DBusProxyBase,
+ public std::enable_shared_from_this<DBusDaemonProxy> {
public:
typedef Event<std::string, std::string, std::string> NameOwnerChangedEvent;
@@ -53,6 +59,10 @@ class DBusDaemonProxy : public DBusProxyBase {
COMMONAPI_EXPORT virtual bool isAvailable() const;
COMMONAPI_EXPORT virtual bool isAvailableBlocking() const;
+ COMMONAPI_EXPORT virtual std::future<AvailabilityStatus> isAvailableAsync(
+ isAvailableAsyncCallback _callback,
+ const CallInfo *_info) const;
+
COMMONAPI_EXPORT virtual ProxyStatusEvent& getProxyStatusEvent();
COMMONAPI_EXPORT virtual InterfaceVersionAttribute& getInterfaceVersionAttribute();
@@ -64,14 +74,54 @@ class DBusDaemonProxy : public DBusProxyBase {
COMMONAPI_EXPORT NameOwnerChangedEvent& getNameOwnerChangedEvent();
COMMONAPI_EXPORT void listNames(CommonAPI::CallStatus& callStatus, std::vector<std::string>& busNames) const;
- COMMONAPI_EXPORT std::future<CallStatus> listNamesAsync(ListNamesAsyncCallback listNamesAsyncCallback) const;
+
+ template <typename DelegateObjectType>
+ COMMONAPI_EXPORT std::future<CallStatus> listNamesAsync(typename DBusProxyAsyncCallbackHandler<DelegateObjectType,
+ std::vector<std::string>>::Delegate& delegate) const {
+ DBusMessage dbusMessage = createMethodCall("ListNames", "");
+ return getDBusConnection()->sendDBusMessageWithReplyAsync(
+ dbusMessage,
+ DBusProxyAsyncCallbackHandler<DelegateObjectType, std::vector<std::string>>::create(delegate, std::tuple<std::vector<std::string>>()),
+ &daemonProxyInfo);
+ }
COMMONAPI_EXPORT void nameHasOwner(const std::string& busName, CommonAPI::CallStatus& callStatus, bool& hasOwner) const;
- COMMONAPI_EXPORT std::future<CallStatus> nameHasOwnerAsync(const std::string& busName,
- NameHasOwnerAsyncCallback nameHasOwnerAsyncCallback) const;
+ template <typename DelegateObjectType>
+ COMMONAPI_EXPORT std::future<CallStatus> nameHasOwnerAsync(const std::string& busName,
+ typename DBusProxyAsyncCallbackHandler<DelegateObjectType,
+ bool>::Delegate& delegate) const {
+ DBusMessage dbusMessage = createMethodCall("NameHasOwner", "s");
+
+ DBusOutputStream outputStream(dbusMessage);
+ const bool success = DBusSerializableArguments<std::string>::serialize(outputStream, busName);
+ if (!success) {
+ std::promise<CallStatus> promise;
+ promise.set_value(CallStatus::OUT_OF_MEMORY);
+ return promise.get_future();
+ }
+ outputStream.flush();
+
+ return getDBusConnection()->sendDBusMessageWithReplyAsync(
+ dbusMessage,
+ DBusProxyAsyncCallbackHandler<DelegateObjectType, bool>::create(delegate, std::tuple<bool>()),
+ &daemonProxyInfo);
+ }
+
+ template <typename DelegateObjectType>
COMMONAPI_EXPORT std::future<CallStatus> getManagedObjectsAsync(const std::string& forDBusServiceName,
- GetManagedObjectsAsyncCallback) const;
+ typename DBusProxyAsyncCallbackHandler<DelegateObjectType,
+ DBusObjectToInterfaceDict>::Delegate& delegate) const {
+ static DBusAddress address(forDBusServiceName, "/", "org.freedesktop.DBus.ObjectManager");
+ auto dbusMethodCallMessage = DBusMessage::createMethodCall(address, "GetManagedObjects", "");
+
+ return getDBusConnection()->sendDBusMessageWithReplyAsync(
+ dbusMethodCallMessage,
+ DBusProxyAsyncCallbackHandler<DelegateObjectType, DBusObjectToInterfaceDict>::create(
+ delegate, std::tuple<DBusObjectToInterfaceDict>()
+ ),
+ &daemonProxyInfo);
+ }
/**
* Get the unique connection/bus name of the primary owner of the name given
@@ -81,7 +131,26 @@ class DBusDaemonProxy : public DBusProxyBase {
*
* @return CallStatus::REMOTE_ERROR if the name is unknown, otherwise CallStatus::SUCCESS and the uniq name of the owner
*/
- std::future<CallStatus> getNameOwnerAsync(const std::string& busName, GetNameOwnerAsyncCallback getNameOwnerAsyncCallback) const;
+ template <typename DelegateObjectType>
+ std::future<CallStatus> getNameOwnerAsync(const std::string& busName,
+ typename DBusProxyAsyncCallbackHandler<DelegateObjectType,
+ std::string>::Delegate& delegate) const {
+ DBusMessage dbusMessage = createMethodCall("GetNameOwner", "s");
+
+ DBusOutputStream outputStream(dbusMessage);
+ const bool success = DBusSerializableArguments<std::string>::serialize(outputStream, busName);
+ if (!success) {
+ std::promise<CallStatus> promise;
+ promise.set_value(CallStatus::OUT_OF_MEMORY);
+ return promise.get_future();
+ }
+ outputStream.flush();
+
+ return getDBusConnection()->sendDBusMessageWithReplyAsync(
+ dbusMessage,
+ DBusProxyAsyncCallbackHandler<DelegateObjectType, std::string>::create(delegate, std::tuple<std::string>()),
+ &daemonProxyInfo);
+ }
private:
DBusEvent<NameOwnerChangedEvent, std::string, std::string, std::string> nameOwnerChangedEvent_;
diff --git a/include/CommonAPI/DBus/DBusFactory.hpp b/include/CommonAPI/DBus/DBusFactory.hpp
index fda0129..6ce0c7e 100644
--- a/include/CommonAPI/DBus/DBusFactory.hpp
+++ b/include/CommonAPI/DBus/DBusFactory.hpp
@@ -10,6 +10,7 @@
#ifndef COMMONAPI_DBUS_FACTORY_HPP_
#define COMMONAPI_DBUS_FACTORY_HPP_
+#include <list>
#include <map>
#include <CommonAPI/Export.hpp>
@@ -24,6 +25,8 @@ class DBusProxy;
class DBusProxyConnection;
class DBusStubAdapter;
+typedef void (*InterfaceInitFunction)(void);
+
typedef std::shared_ptr<DBusProxy>
(*ProxyCreateFunction)(const DBusAddress &_address,
const std::shared_ptr<DBusProxyConnection> &_connection);
@@ -40,6 +43,8 @@ public:
COMMONAPI_EXPORT Factory();
COMMONAPI_EXPORT virtual ~Factory();
+ COMMONAPI_EXPORT void init();
+
COMMONAPI_EXPORT void registerProxyCreateMethod(const std::string &_address,
ProxyCreateFunction _function);
@@ -84,6 +89,13 @@ public:
COMMONAPI_EXPORT bool registerManagedService(const std::shared_ptr<DBusStubAdapter> &_adapter);
COMMONAPI_EXPORT bool unregisterManagedService(const std::string &_address);
+ COMMONAPI_EXPORT void incrementConnection(std::shared_ptr<DBusProxyConnection>);
+ COMMONAPI_EXPORT void decrementConnection(std::shared_ptr<DBusProxyConnection>);
+ COMMONAPI_EXPORT void releaseConnection(const ConnectionId_t&, MainLoopContext*);
+
+ // Initialization
+ COMMONAPI_EXPORT void registerInterface(InterfaceInitFunction _function);
+
private:
COMMONAPI_EXPORT std::shared_ptr<DBusConnection> getConnection(const ConnectionId_t &);
COMMONAPI_EXPORT std::shared_ptr<DBusConnection> getConnection(std::shared_ptr<MainLoopContext>);
@@ -97,7 +109,10 @@ private:
private:
static std::shared_ptr<Factory> theFactory;
+ std::mutex connectionsMutex_;
std::map<ConnectionId_t, std::shared_ptr<DBusConnection>> connections_;
+
+ std::mutex contextConnectionsMutex_;
std::map<MainLoopContext *, std::shared_ptr<DBusConnection>> contextConnections_;
std::map<std::string, ProxyCreateFunction> proxyCreateFunctions_;
@@ -105,7 +120,9 @@ private:
ServicesMap services_;
- DBusType_t dBusBusType_;
+ std::list<InterfaceInitFunction> initializers_;
+ std::mutex initializerMutex_;
+ bool isInitialized_;
};
} // namespace DBus
diff --git a/include/CommonAPI/DBus/DBusFreedesktopPropertiesStub.hpp b/include/CommonAPI/DBus/DBusFreedesktopPropertiesStub.hpp
index 1c01da9..bc31a89 100644
--- a/include/CommonAPI/DBus/DBusFreedesktopPropertiesStub.hpp
+++ b/include/CommonAPI/DBus/DBusFreedesktopPropertiesStub.hpp
@@ -47,7 +47,7 @@ private:
std::weak_ptr<DBusProxyConnection> connection_;
std::shared_ptr<DBusStubAdapter> adapter_;
- typedef std::unordered_map<std::string, std::shared_ptr<DBusStubAdapter>> DBusInterfacesMap;
+ typedef std::unordered_map<std::string, std::vector<std::shared_ptr<DBusStubAdapter>>> DBusInterfacesMap;
DBusInterfacesMap managedInterfaces_;
std::mutex dbusInterfacesLock_;
diff --git a/include/CommonAPI/DBus/DBusFreedesktopStubAdapterHelper.hpp b/include/CommonAPI/DBus/DBusFreedesktopStubAdapterHelper.hpp
index 4593400..ec55f4e 100644
--- a/include/CommonAPI/DBus/DBusFreedesktopStubAdapterHelper.hpp
+++ b/include/CommonAPI/DBus/DBusFreedesktopStubAdapterHelper.hpp
@@ -13,6 +13,16 @@
#include <CommonAPI/Struct.hpp>
#include <CommonAPI/DBus/DBusStubAdapterHelper.hpp>
+# if _MSC_VER >= 1300
+/*
+* Diamond inheritance is used for the DBusSetAttributeStubDispatcher base class.
+* The Microsoft compiler put warning (C4250) using a desired c++ feature: "Delegating to a sister class"
+* A powerful technique that arises from using virtual inheritance is to delegate a method from a class in another class
+* by using a common abstract base class. This is also called cross delegation.
+*/
+# pragma warning( disable : 4250 )
+# endif
+
namespace CommonAPI {
namespace DBus {
@@ -139,46 +149,26 @@ struct DBusStubFreedesktopPropertiesSignalHelper;
template<typename DataType_, typename DeplType_>
struct DBusStubFreedesktopPropertiesSignalHelper {
- template <typename ValueType_>
- struct DBusPropertiesEntry
- : public CommonAPI::Struct<std::string, CommonAPI::Variant<ValueType_>> {
-
- DBusPropertiesEntry() = default;
- DBusPropertiesEntry(const std::string &_propertyName,
- const ValueType_ &_propertyValue) {
- std::get<0>(this->values_) = _propertyName;
- std::get<1>(this->values_) = _propertyValue;
- };
-
- const std::string &getPropertyName() const { return std::get<0>(this->values_); }
- void setPropertyName(const std::string &_value) { std::get<0>(this->values_) = _value; }
-
- const ValueType_ getPropertyValue() const { return std::get<1>(this->values_); }
- void setPropertyValue(const ValueType_ &_value) { std::get<1>(this->values_) = _value; }
- };
-
- typedef std::vector<DBusPropertiesEntry<DataType_>> PropertiesArray;
- typedef CommonAPI::Deployment<CommonAPI::EmptyDeployment, VariantDeployment<DeplType_>> PropertyDeployment;
- typedef CommonAPI::ArrayDeployment<PropertyDeployment> PropertiesDeployment;
- typedef CommonAPI::Deployable<PropertiesArray, PropertiesDeployment> DeployedPropertiesArray;
+ typedef std::unordered_map<std::string, Variant<DataType_>> PropertyMap;
+ typedef MapDeployment<EmptyDeployment, VariantDeployment<DeplType_>> PropertyMapDeployment;
+ typedef Deployable<PropertyMap, PropertyMapDeployment> DeployedPropertyMap;
template <typename StubClass_>
static bool sendPropertiesChangedSignal(const StubClass_ &_stub, const std::string &_propertyName, const DataType_ &_inArg, DeplType_ *_depl) {
const std::vector<std::string> invalidatedProperties;
- PropertiesArray changedProperties;
- DBusPropertiesEntry<DataType_> entry(_propertyName, _inArg);
- changedProperties.push_back(entry);
- VariantDeployment<DeplType_> actualDepl(true, _depl);
- PropertyDeployment propertyDeployment(nullptr, &actualDepl);
- PropertiesDeployment changedPropertiesDeployment(&propertyDeployment);
+ // fill out property map
+ PropertyMap changedProperties;
+ changedProperties[_propertyName] = _inArg;
- DeployedPropertiesArray deployedChangedProperties(changedProperties, &changedPropertiesDeployment);
+ VariantDeployment<DeplType_> actualDepl(true, _depl);
+ PropertyMapDeployment changedPropertiesDeployment(nullptr, &actualDepl);
+ DeployedPropertyMap deployedChangedProperties(changedProperties, &changedPropertiesDeployment);
return DBusStubSignalHelper<
DBusSerializableArguments<
const std::string,
- DeployedPropertiesArray,
+ DeployedPropertyMap,
std::vector<std::string>
>
>::sendSignal(
diff --git a/include/CommonAPI/DBus/DBusInputStream.hpp b/include/CommonAPI/DBus/DBusInputStream.hpp
index 9a3f74d..ec6c7d0 100644
--- a/include/CommonAPI/DBus/DBusInputStream.hpp
+++ b/include/CommonAPI/DBus/DBusInputStream.hpp
@@ -14,11 +14,11 @@
#include <iomanip>
#include <sstream>
-#include <cassert>
#include <cstdint>
#include <stack>
#include <string>
#include <vector>
+#include <cstring>
#include <CommonAPI/Export.hpp>
#include <CommonAPI/InputStream.hpp>
@@ -73,7 +73,7 @@ public:
COMMONAPI_EXPORT InputStream &readValue(Version &_value, const EmptyDeployment *_depl);
COMMONAPI_EXPORT void beginReadMapOfSerializableStructs() {
- uint32_t itsSize;
+ uint32_t itsSize(0);
_readValue(itsSize);
pushSize(itsSize);
align(8); /* correct alignment for first DICT_ENTRY */
@@ -90,10 +90,12 @@ public:
}
COMMONAPI_EXPORT InputStream &skipMap() {
- uint32_t itsSize;
+ uint32_t itsSize(0);
_readValue(itsSize);
align(8); /* skip padding (if any) */
- assert(itsSize <= (sizes_.top() + positions_.top() - current_));
+ if (itsSize > (sizes_.top() + positions_.top() - current_)) {
+ COMMONAPI_ERROR(std::string(__FUNCTION__) + ": size ", itsSize, " exceeds remaining ", (sizes_.top() + positions_.top() - current_));
+ }
_readRaw(itsSize);
return (*this);
}
@@ -103,6 +105,10 @@ public:
Base_ tmpValue;
readValue(tmpValue, _depl);
_value = tmpValue;
+
+ if(!_value.validate()) {
+ setError();
+ }
return (*this);
}
@@ -118,7 +124,7 @@ public:
template<class Deployment_, class PolymorphicStruct_>
COMMONAPI_EXPORT InputStream &readValue(std::shared_ptr<PolymorphicStruct_> &_value,
const Deployment_ *_depl) {
- uint32_t serial;
+ uint32_t serial(0);
align(8);
_readValue(serial);
skipSignature();
@@ -135,8 +141,13 @@ public:
COMMONAPI_EXPORT InputStream &readValue(Variant<Types_...> &_value, const CommonAPI::EmptyDeployment *_depl = nullptr) {
(void)_depl;
if(_value.hasValue()) {
- DeleteVisitor<_value.maxSize> visitor(_value.valueStorage_);
- ApplyVoidVisitor<DeleteVisitor<_value.maxSize>,
+#if _MSC_VER < 1900
+ const auto maxSize = Variant<Types_...>::maxSize;
+#else
+ constexpr auto maxSize = Variant<Types_...>::maxSize;
+#endif
+ DeleteVisitor<maxSize> visitor(_value.valueStorage_);
+ ApplyVoidVisitor<DeleteVisitor<maxSize>,
Variant<Types_...>, Types_... >::visit(visitor, _value);
}
@@ -154,8 +165,13 @@ public:
template<typename Deployment_, typename... Types_>
COMMONAPI_EXPORT InputStream &readValue(Variant<Types_...> &_value, const Deployment_ *_depl) {
if(_value.hasValue()) {
- DeleteVisitor<_value.maxSize> visitor(_value.valueStorage_);
- ApplyVoidVisitor<DeleteVisitor<_value.maxSize>,
+#if _MSC_VER < 1900
+ const auto maxSize = Variant<Types_...>::maxSize;
+#else
+ constexpr auto maxSize = Variant<Types_...>::maxSize;
+#endif
+ DeleteVisitor<maxSize> visitor(_value.valueStorage_);
+ ApplyVoidVisitor<DeleteVisitor<maxSize>,
Variant<Types_...>, Types_... >::visit(visitor, _value);
}
@@ -163,20 +179,32 @@ public:
// Read signature
uint8_t signatureLength;
readValue(signatureLength, static_cast<EmptyDeployment *>(nullptr));
- std::string signature(_readRaw(signatureLength+1), signatureLength);
-
- // Determine index (value type) from signature
- TypeCompareVisitor<Types_...> visitor(signature);
- bool success = ApplyTypeCompareVisitor<
- TypeCompareVisitor<Types_...>,
- Variant<Types_...>,
- Deployment_,
- Types_...
- >::visit(visitor, _value, _depl, _value.valueType_);
- if (!success) {
- _value.valueType_ = 0; // Invalid index
- setError();
+ char * raw = _readRaw(signatureLength+1);
+ if (hasError()) {
return (*this);
+ } else {
+ std::string signature(raw, signatureLength);
+
+ // Determine index (value type) from signature
+ TypeCompareVisitor<Types_...> visitor(signature);
+ bool success = ApplyTypeCompareVisitor<
+ TypeCompareVisitor<Types_...>,
+ Variant<Types_...>,
+ Deployment_,
+ Types_...
+ >::visit(visitor, _value, _depl, _value.valueType_);
+ /*
+ * It is possible that this ApplyTypeCompareVisitor fails on purpose,
+ * if the data type of the variant does not match the data type in the stream.
+ * This can happen for instance with the Freedesktop messages that return
+ * data in variants, but we don't have any idea _which variant_ until we've
+ * tried to stream the value in the ApplyTypeComputerVisitor.
+ */
+ if (!success) {
+ _value.valueType_ = 0; // Invalid index signifying 'no value'
+ setError();
+ return (*this);
+ }
}
} else {
align(8);
@@ -196,7 +224,7 @@ public:
COMMONAPI_EXPORT InputStream &readValue(std::vector<ElementType_> &_value, const EmptyDeployment *_depl) {
(void)_depl;
- uint32_t itsSize;
+ uint32_t itsSize(0);
_readValue(itsSize);
pushSize(itsSize);
@@ -222,9 +250,27 @@ public:
return (*this);
}
+ COMMONAPI_EXPORT InputStream &readValue(std::vector<uint8_t> &_value, const EmptyDeployment *_depl) {
+ (void)_depl;
+
+ uint32_t itsSize(0);
+ _readValue(itsSize);
+
+ alignVector<uint8_t>();
+
+ uint8_t *data = reinterpret_cast<uint8_t *>(_readRaw(itsSize));
+ if (!hasError()) {
+ _value.resize(itsSize);
+ std::memcpy(_value.data(), data, itsSize);
+ }
+
+ return (*this);
+ }
+
+
template<class Deployment_, typename ElementType_>
COMMONAPI_EXPORT InputStream &readValue(std::vector<ElementType_> &_value, const Deployment_ *_depl) {
- uint32_t itsSize;
+ uint32_t itsSize(0);
_readValue(itsSize);
pushSize(itsSize);
@@ -256,7 +302,7 @@ public:
typedef typename std::unordered_map<KeyType_, ValueType_, HasherType_>::value_type MapElement;
- uint32_t itsSize;
+ uint32_t itsSize(0);
_readValue(itsSize);
pushSize(itsSize);
@@ -291,7 +337,7 @@ public:
typedef typename std::unordered_map<KeyType_, ValueType_, HasherType_>::value_type MapElement;
- uint32_t itsSize;
+ uint32_t itsSize(0);
_readValue(itsSize);
pushSize(itsSize);
@@ -395,7 +441,10 @@ public:
if (sizeof(_value) > 1)
align(sizeof(Type_));
- _value = *(reinterpret_cast<Type_ *>(_readRaw(sizeof(Type_))));
+ char * raw = _readRaw(sizeof(Type_));
+ if (!hasError()) {
+ _value = *(reinterpret_cast<Type_ *>(raw));
+ }
return (*this);
}
@@ -403,7 +452,10 @@ public:
COMMONAPI_EXPORT DBusInputStream &_readValue(float &_value) {
align(sizeof(double));
- _value = (float) (*(reinterpret_cast<double*>(_readRaw(sizeof(double)))));
+ char * raw = _readRaw(sizeof(double));
+ if (!hasError()) {
+ _value = (float) (*(reinterpret_cast<double*>(raw)));
+ }
return (*this);
}
@@ -415,7 +467,7 @@ private:
COMMONAPI_EXPORT size_t popSize();
inline void skipSignature() {
- uint8_t length;
+ uint8_t length(0);
_readValue(length);
_readRaw(length + 1);
}
diff --git a/include/CommonAPI/DBus/DBusInstanceAvailabilityStatusChangedEvent.hpp b/include/CommonAPI/DBus/DBusInstanceAvailabilityStatusChangedEvent.hpp
index 6c6c9e1..ec2d70f 100644
--- a/include/CommonAPI/DBus/DBusInstanceAvailabilityStatusChangedEvent.hpp
+++ b/include/CommonAPI/DBus/DBusInstanceAvailabilityStatusChangedEvent.hpp
@@ -80,14 +80,18 @@ class DBusInstanceAvailabilityStatusChangedEvent:
DBusInterfacesAndPropertiesDict dbusInterfacesAndPropertiesDict;
dbusInputStream >> dbusObjectPath;
- assert(!dbusInputStream.hasError());
+ if (dbusInputStream.hasError()) {
+ COMMONAPI_ERROR(std::string(__FUNCTION__) + " failed to read object path");
+ }
dbusInputStream.beginReadMapOfSerializableStructs();
while (!dbusInputStream.readMapCompleted()) {
dbusInputStream.align(8);
dbusInputStream >> dbusInterfaceName;
dbusInputStream.skipMap();
- assert(!dbusInputStream.hasError());
+ if (dbusInputStream.hasError()) {
+ COMMONAPI_ERROR(std::string(__FUNCTION__) + " failed to read interface name");
+ }
if(dbusInterfaceName == observedInterfaceName_) {
notifyInterfaceStatusChanged(dbusObjectPath, dbusInterfaceName, AvailabilityStatus::AVAILABLE);
}
@@ -101,10 +105,14 @@ class DBusInstanceAvailabilityStatusChangedEvent:
std::vector<std::string> dbusInterfaceNames;
dbusInputStream >> dbusObjectPath;
- assert(!dbusInputStream.hasError());
+ if (dbusInputStream.hasError()) {
+ COMMONAPI_ERROR(std::string(__FUNCTION__) + " failed to read object path");
+ }
dbusInputStream >> dbusInterfaceNames;
- assert(!dbusInputStream.hasError());
+ if (dbusInputStream.hasError()) {
+ COMMONAPI_ERROR(std::string(__FUNCTION__) + " failed to read interface names");
+ }
for (const auto& dbusInterfaceName : dbusInterfaceNames) {
if(dbusInterfaceName == observedInterfaceName_) {
diff --git a/include/CommonAPI/DBus/DBusMainLoop.hpp b/include/CommonAPI/DBus/DBusMainLoop.hpp
index 2fff847..b09a8f1 100755
--- a/include/CommonAPI/DBus/DBusMainLoop.hpp
+++ b/include/CommonAPI/DBus/DBusMainLoop.hpp
@@ -75,6 +75,8 @@ class DBusMainLoop {
COMMONAPI_EXPORT void wakeup();
COMMONAPI_EXPORT void wakeupAck();
+ COMMONAPI_EXPORT void cleanup();
+
COMMONAPI_EXPORT void registerFileDescriptor(const DBusMainLoopPollFd& fileDescriptor);
COMMONAPI_EXPORT void unregisterFileDescriptor(const DBusMainLoopPollFd& fileDescriptor);
@@ -158,9 +160,9 @@ class DBusMainLoop {
std::mutex watchesMutex_;
std::mutex timeoutsMutex_;
- std::set<DispatchSourceToDispatchStruct*> sourcesToDispatch_;
- std::set<WatchToDispatchStruct*> watchesToDispatch_;
- std::set<TimeoutToDispatchStruct*> timeoutsToDispatch_;
+ std::set<std::pair<DispatchPriority, DispatchSourceToDispatchStruct*>> sourcesToDispatch_;
+ std::set<std::pair<DispatchPriority, WatchToDispatchStruct*>> watchesToDispatch_;
+ std::set<std::pair<DispatchPriority, TimeoutToDispatchStruct*>> timeoutsToDispatch_;
DispatchSourceListenerSubscription dispatchSourceListenerSubscription_;
WatchListenerSubscription watchListenerSubscription_;
diff --git a/include/CommonAPI/DBus/DBusMainLoopContext.hpp b/include/CommonAPI/DBus/DBusMainLoopContext.hpp
index 8cf9cf2..c048c90 100644
--- a/include/CommonAPI/DBus/DBusMainLoopContext.hpp
+++ b/include/CommonAPI/DBus/DBusMainLoopContext.hpp
@@ -12,11 +12,14 @@
#include <list>
#include <memory>
+#include <queue>
#include <dbus/dbus.h>
#include <CommonAPI/MainLoopContext.hpp>
+#include <CommonAPI/DBus/DBusProxyConnection.hpp>
+
namespace CommonAPI {
namespace DBus {
@@ -35,9 +38,26 @@ class DBusDispatchSource: public DispatchSource {
DBusConnection* dbusConnection_;
};
+class DBusMessageWatch;
+class DBusMessageDispatchSource: public DispatchSource {
+ public:
+ DBusMessageDispatchSource(DBusMessageWatch* watch);
+ virtual ~DBusMessageDispatchSource();
+
+ bool prepare(int64_t& timeout);
+ bool check();
+ bool dispatch();
+
+ private:
+ DBusMessageWatch* watch_;
+
+ std::mutex watchMutex_;
+};
+
class DBusWatch: public Watch {
public:
- DBusWatch(::DBusWatch* libdbusWatch, std::weak_ptr<MainLoopContext>& mainLoopContext);
+ DBusWatch(::DBusWatch* libdbusWatch, std::weak_ptr<MainLoopContext>& mainLoopContext,
+ std::weak_ptr<DBusConnection>& dbusConnection);
bool isReadyToBeWatched();
void startWatching();
@@ -61,10 +81,81 @@ class DBusWatch: public Watch {
std::vector<DispatchSource*> dependentDispatchSources_;
std::weak_ptr<MainLoopContext> mainLoopContext_;
+ std::weak_ptr<DBusConnection> dbusConnection_;
+
+#ifdef WIN32
+ HANDLE wsaEvent_;
+#endif
+};
+
+class DBusMessageWatch : public Watch {
+public:
+
+ struct MsgQueueEntry {
+ MsgQueueEntry(DBusMessage _message) :
+ message_(_message) { }
+ DBusMessage message_;
+
+ virtual void process(std::shared_ptr<DBusConnection> _connection) = 0;
+ virtual void clear();
+ };
+
+ struct MsgReplyQueueEntry : MsgQueueEntry {
+ MsgReplyQueueEntry(DBusProxyConnection::DBusMessageReplyAsyncHandler* _replyAsyncHandler,
+ DBusMessage _reply) :
+ MsgQueueEntry(_reply),
+ replyAsyncHandler_(_replyAsyncHandler) { }
+
+ DBusProxyConnection::DBusMessageReplyAsyncHandler* replyAsyncHandler_;
+
+ void process(std::shared_ptr<DBusConnection> _connection);
+ void clear();
+ };
+
+ DBusMessageWatch(std::shared_ptr<DBusConnection> _connection);
+ virtual ~DBusMessageWatch();
+
+ void dispatch(unsigned int eventFlags);
+
+ const pollfd& getAssociatedFileDescriptor();
#ifdef WIN32
+ const HANDLE& getAssociatedEvent();
+#endif
+
+ const std::vector<DispatchSource*>& getDependentDispatchSources();
+
+ void addDependentDispatchSource(CommonAPI::DispatchSource* _dispatchSource);
+
+ void removeDependentDispatchSource(CommonAPI::DispatchSource* _dispatchSource);
+
+ void pushMsgQueue(std::shared_ptr<MsgQueueEntry> _queueEntry);
+
+ void popMsgQueue();
+
+ std::shared_ptr<MsgQueueEntry> frontMsgQueue();
+
+ bool emptyMsgQueue();
+
+ void processMsgQueueEntry(std::shared_ptr<MsgQueueEntry> _queueEntry);
+
+private:
+ int pipeFileDescriptors_[2];
+
+ pollfd pollFileDescriptor_;
+ std::vector<CommonAPI::DispatchSource*> dependentDispatchSources_;
+ std::queue<std::shared_ptr<MsgQueueEntry>> msgQueue_;
+
+ std::mutex msgQueueMutex_;
+
+ std::weak_ptr<DBusConnection> connection_;
+
+ 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 0519e9d..b005904 100644
--- a/include/CommonAPI/DBus/DBusMessage.hpp
+++ b/include/CommonAPI/DBus/DBusMessage.hpp
@@ -93,6 +93,8 @@ public:
bool setBodyLength(const int bodyLength);
bool setDestination(const char* destination);
+ void setSerial(const unsigned int serial) const;
+
private:
::DBusMessage *message_;
diff --git a/include/CommonAPI/DBus/DBusObjectManager.hpp b/include/CommonAPI/DBus/DBusObjectManager.hpp
index e2ec2c5..2d36aaf 100644
--- a/include/CommonAPI/DBus/DBusObjectManager.hpp
+++ b/include/CommonAPI/DBus/DBusObjectManager.hpp
@@ -50,8 +50,9 @@ class DBusObjectManager {
COMMONAPI_EXPORT bool onFreedesktopPropertiesDBusMessage(const DBusMessage& callMessage);
- typedef std::unordered_map<DBusInterfaceHandlerPath, std::shared_ptr<DBusInterfaceHandler>> DBusRegisteredObjectsTable;
+ typedef std::unordered_map<DBusInterfaceHandlerPath, std::vector<std::shared_ptr<DBusInterfaceHandler>>> DBusRegisteredObjectsTable;
DBusRegisteredObjectsTable dbusRegisteredObjectsTable_;
+ COMMONAPI_EXPORT bool addToRegisteredObjectsTable(DBusInterfaceHandlerPath ifpath, std::shared_ptr<DBusInterfaceHandler> handler);
std::shared_ptr<DBusObjectManagerStub> rootDBusObjectManagerStub_;
diff --git a/include/CommonAPI/DBus/DBusObjectManagerStub.hpp b/include/CommonAPI/DBus/DBusObjectManagerStub.hpp
index 6d88951..de8495d 100644
--- a/include/CommonAPI/DBus/DBusObjectManagerStub.hpp
+++ b/include/CommonAPI/DBus/DBusObjectManagerStub.hpp
@@ -112,7 +112,7 @@ public:
std::string dbusObjectPath_;
std::weak_ptr<DBusProxyConnection> dbusConnection_;
- typedef std::unordered_map<std::string, std::shared_ptr<DBusStubAdapter>> DBusInterfacesMap;
+ typedef std::unordered_map<std::string, std::vector<std::shared_ptr<DBusStubAdapter>>> DBusInterfacesMap;
typedef std::unordered_map<std::string, DBusInterfacesMap> DBusObjectPathsMap;
DBusObjectPathsMap registeredDBusObjectPathsMap_;
diff --git a/include/CommonAPI/DBus/DBusOutputStream.hpp b/include/CommonAPI/DBus/DBusOutputStream.hpp
index b99c9c8..6814430 100644
--- a/include/CommonAPI/DBus/DBusOutputStream.hpp
+++ b/include/CommonAPI/DBus/DBusOutputStream.hpp
@@ -10,7 +10,6 @@
#ifndef COMMONAPI_DBUS_DBUSOUTPUTSTREAM_HPP_
#define COMMONAPI_DBUS_DBUSOUTPUTSTREAM_HPP_
-#include <cassert>
#include <cstring>
#include <memory>
#include <stack>
@@ -231,6 +230,14 @@ public:
return (*this);
}
+ COMMONAPI_EXPORT OutputStream &writeValue(const std::vector<uint8_t> &_value,
+ const EmptyDeployment *_depl) {
+ (void)_depl;
+ align(sizeof(uint32_t));
+ writeByteBuffer(_value.data(), static_cast<uint32_t>(_value.size()));
+ return (*this);
+ }
+
template<class Deployment_, typename ElementType_>
COMMONAPI_EXPORT OutputStream &writeValue(const std::vector<ElementType_> &_value,
const Deployment_ *_depl) {
@@ -405,13 +412,17 @@ private:
template<typename Type_>
COMMONAPI_EXPORT void _writeValueAt(size_t _position, const Type_ &_value) {
- assert(_position + sizeof(Type_) <= payload_.size());
+ if ((_position + sizeof(Type_)) > payload_.size()) {
+ COMMONAPI_ERROR(std::string(__FUNCTION__) + ": payload size ", payload_.size(), " too small ", (_position + sizeof(Type_)));
+ }
_writeRawAt(reinterpret_cast<const char *>(&_value),
sizeof(Type_), _position);
}
COMMONAPI_EXPORT DBusOutputStream &writeString(const char *_data, const uint32_t &_length);
+ COMMONAPI_EXPORT DBusOutputStream &writeByteBuffer(const uint8_t *_date, const uint32_t &_length);
+
/**
* Takes sizeInByte characters, starting from the character which val points to, and stores them for later writing.
* When calling flush(), all values that were written to this stream are copied into the payload of the #DBusMessage.
diff --git a/include/CommonAPI/DBus/DBusProxy.hpp b/include/CommonAPI/DBus/DBusProxy.hpp
index 04f2ca9..c8a57bc 100644
--- a/include/CommonAPI/DBus/DBusProxy.hpp
+++ b/include/CommonAPI/DBus/DBusProxy.hpp
@@ -36,8 +36,9 @@ class DBusProxyStatusEvent
};
-class DBusProxy
- : public DBusProxyBase {
+class COMMONAPI_EXPORT_CLASS_EXPLICIT DBusProxy
+ : public DBusProxyBase,
+ public std::enable_shared_from_this<DBusProxy> {
public:
COMMONAPI_EXPORT DBusProxy(const DBusAddress &_address,
const std::shared_ptr<DBusProxyConnection> &_connection);
@@ -48,14 +49,20 @@ public:
COMMONAPI_EXPORT virtual bool isAvailable() const;
COMMONAPI_EXPORT virtual bool isAvailableBlocking() const;
+ COMMONAPI_EXPORT virtual std::future<AvailabilityStatus> isAvailableAsync(
+ isAvailableAsyncCallback _callback,
+ const CallInfo *_info) const;
- COMMONAPI_EXPORT DBusProxyConnection::DBusSignalHandlerToken subscribeForSelectiveBroadcastOnConnection(
- bool& subscriptionAccepted,
+ COMMONAPI_EXPORT void subscribeForSelectiveBroadcastOnConnection(
const std::string& objectPath,
const std::string& interfaceName,
const std::string& interfaceMemberName,
const std::string& interfaceMemberSignature,
- DBusProxyConnection::DBusSignalHandler* dbusSignalHandler);
+ DBusProxyConnection::DBusSignalHandler* dbusSignalHandler,
+ uint32_t tag);
+
+ COMMONAPI_EXPORT void insertSelectiveSubscription(const std::string& interfaceMemberName,
+ DBusProxyConnection::DBusSignalHandler* dbusSignalHandler, uint32_t tag);
COMMONAPI_EXPORT void unsubscribeFromSelectiveBroadcast(const std::string& eventName,
DBusProxyConnection::DBusSignalHandlerToken subscription,
const DBusProxyConnection::DBusSignalHandler* dbusSignalHandler);
@@ -119,10 +126,11 @@ private:
const uint32_t tag);
COMMONAPI_EXPORT void addSignalMemberHandlerToQueue(SignalMemberHandlerTuple& _signalMemberHandler);
+ COMMONAPI_EXPORT void availabilityTimeoutThreadHandler() const;
+
DBusProxyStatusEvent dbusProxyStatusEvent_;
DBusServiceRegistry::DBusServiceSubscription dbusServiceRegistrySubscription_;
AvailabilityStatus availabilityStatus_;
- mutable std::mutex availabilityStatusMutex_;
DBusReadonlyAttribute<InterfaceVersionAttribute> interfaceVersionAttribute_;
@@ -132,11 +140,22 @@ private:
mutable std::condition_variable availabilityCondition_;
std::list<SignalMemberHandlerTuple> signalMemberHandlerQueue_;
- CallInfo signalMemberHandlerInfo_;
mutable std::mutex signalMemberHandlerQueueMutex_;
- std::map<std::string, DBusProxyConnection::DBusSignalHandler*> selectiveBroadcastHandlers;
+ std::map<std::string, std::pair<DBusProxyConnection::DBusSignalHandler*, uint32_t>> selectiveBroadcastHandlers;
mutable std::mutex selectiveBroadcastHandlersMutex_;
+
+ mutable std::shared_ptr<std::thread> availabilityTimeoutThread_;
+ mutable std::mutex availabilityTimeoutThreadMutex_;
+ mutable std::mutex timeoutsMutex_;
+ mutable std::condition_variable availabilityTimeoutCondition_;
+
+ typedef std::tuple<
+ std::chrono::time_point<std::chrono::high_resolution_clock>,
+ isAvailableAsyncCallback,
+ std::promise<AvailabilityStatus>
+ > AvailabilityTimeout_t;
+ mutable std::list<AvailabilityTimeout_t> timeouts_;
};
diff --git a/include/CommonAPI/DBus/DBusProxyAsyncCallbackHandler.hpp b/include/CommonAPI/DBus/DBusProxyAsyncCallbackHandler.hpp
index 0a0ee56..c36ccb1 100644
--- a/include/CommonAPI/DBus/DBusProxyAsyncCallbackHandler.hpp
+++ b/include/CommonAPI/DBus/DBusProxyAsyncCallbackHandler.hpp
@@ -22,21 +22,31 @@
namespace CommonAPI {
namespace DBus {
-template<typename ... ArgTypes_>
+template<typename DelegateObjectType_, typename ... ArgTypes_>
class DBusProxyAsyncCallbackHandler:
public DBusProxyConnection::DBusMessageReplyAsyncHandler {
public:
- typedef std::function<void(CallStatus, ArgTypes_...)> FunctionType;
+
+ struct Delegate {
+ typedef std::function<void(CallStatus, ArgTypes_...)> FunctionType;
+
+ 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(
- FunctionType&& callback, std::tuple<ArgTypes_...> args) {
+ Delegate& delegate, std::tuple<ArgTypes_...> args) {
return std::unique_ptr<DBusProxyConnection::DBusMessageReplyAsyncHandler>(
- new DBusProxyAsyncCallbackHandler(std::move(callback), args));
+ new DBusProxyAsyncCallbackHandler<DelegateObjectType_, ArgTypes_...>(std::move(delegate), args));
}
DBusProxyAsyncCallbackHandler() = delete;
- DBusProxyAsyncCallbackHandler(FunctionType&& callback, std::tuple<ArgTypes_...> args)
- : callback_(std::move(callback)),
+ DBusProxyAsyncCallbackHandler(Delegate&& delegate, std::tuple<ArgTypes_...> args)
+ : delegate_(std::move(delegate)),
args_(args),
executionStarted_(false),
executionFinished_(false),
@@ -67,7 +77,7 @@ class DBusProxyAsyncCallbackHandler:
virtual void setExecutionFinished() {
executionFinished_ = true;
// free assigned std::function<> immediately
- callback_ = [](CallStatus, ArgTypes_...) {};
+ delegate_.function_ = [](CallStatus, ArgTypes_...) {};
}
virtual bool getExecutionFinished() {
@@ -124,12 +134,15 @@ class DBusProxyAsyncCallbackHandler:
}
}
- callback_(callStatus, std::move(std::get<ArgIndices_>(argTuple))...);
+ //check if object is expired
+ if(!delegate_.object_.expired())
+ delegate_.function_(callStatus, std::move(std::get<ArgIndices_>(argTuple))...);
+
return callStatus;
}
std::promise<CallStatus> promise_;
- FunctionType callback_;
+ Delegate delegate_;
std::tuple<ArgTypes_...> args_;
bool executionStarted_;
bool executionFinished_;
diff --git a/include/CommonAPI/DBus/DBusProxyAsyncSignalMemberCallbackHandler.hpp b/include/CommonAPI/DBus/DBusProxyAsyncSignalMemberCallbackHandler.hpp
index f6d7791..11cb354 100644
--- a/include/CommonAPI/DBus/DBusProxyAsyncSignalMemberCallbackHandler.hpp
+++ b/include/CommonAPI/DBus/DBusProxyAsyncSignalMemberCallbackHandler.hpp
@@ -21,22 +21,33 @@
namespace CommonAPI {
namespace DBus {
+template <typename DelegateObjectType_>
class DBusProxyAsyncSignalMemberCallbackHandler: public DBusProxyConnection::DBusMessageReplyAsyncHandler {
public:
- typedef std::function<void(CallStatus, DBusMessage, DBusProxyConnection::DBusSignalHandler*, int)> FunctionType;
+
+ struct Delegate {
+ typedef std::function<void(CallStatus, DBusMessage, DBusProxyConnection::DBusSignalHandler*, uint32_t)> FunctionType;
+
+ 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(
- FunctionType& callback, DBusProxyConnection::DBusSignalHandler* dbusSignalHandler,
- const int tag) {
+ Delegate& delegate, DBusProxyConnection::DBusSignalHandler* dbusSignalHandler,
+ const uint32_t tag) {
return std::unique_ptr<DBusProxyConnection::DBusMessageReplyAsyncHandler>(
- new DBusProxyAsyncSignalMemberCallbackHandler(std::move(callback), dbusSignalHandler, tag));
+ new DBusProxyAsyncSignalMemberCallbackHandler<DelegateObjectType_>(std::move(delegate), dbusSignalHandler, tag));
}
DBusProxyAsyncSignalMemberCallbackHandler() = delete;
- DBusProxyAsyncSignalMemberCallbackHandler(FunctionType&& callback,
+ DBusProxyAsyncSignalMemberCallbackHandler(Delegate&& delegate,
DBusProxyConnection::DBusSignalHandler* dbusSignalHandler,
- const int tag):
- callback_(std::move(callback)), dbusSignalHandler_(dbusSignalHandler), tag_(tag),
+ const uint32_t tag):
+ delegate_(std::move(delegate)), dbusSignalHandler_(dbusSignalHandler), tag_(tag),
executionStarted_(false), executionFinished_(false),
timeoutOccurred_(false), hasToBeDeleted_(false) {
}
@@ -94,14 +105,17 @@ class DBusProxyAsyncSignalMemberCallbackHandler: public DBusProxyConnection::DBu
inline CallStatus handleDBusMessageReply(const CallStatus dbusMessageCallStatus, const DBusMessage& dbusMessage) const {
CallStatus callStatus = dbusMessageCallStatus;
- callback_(callStatus, dbusMessage, dbusSignalHandler_, tag_);
+ //check if object is expired
+ if(!delegate_.object_.expired())
+ delegate_.function_(callStatus, dbusMessage, dbusSignalHandler_, tag_);
+
return callStatus;
}
std::promise<CallStatus> promise_;
- const FunctionType callback_;
+ const Delegate delegate_;
DBusProxyConnection::DBusSignalHandler* dbusSignalHandler_;
- const int tag_;
+ const uint32_t tag_;
bool executionStarted_;
bool executionFinished_;
bool timeoutOccurred_;
diff --git a/include/CommonAPI/DBus/DBusProxyBase.hpp b/include/CommonAPI/DBus/DBusProxyBase.hpp
index 4657bbf..2193ca7 100644
--- a/include/CommonAPI/DBus/DBusProxyBase.hpp
+++ b/include/CommonAPI/DBus/DBusProxyBase.hpp
@@ -26,7 +26,7 @@ namespace DBus {
class DBusAddress;
-class DBusProxyBase
+class COMMONAPI_EXPORT_CLASS_EXPLICIT DBusProxyBase
: public virtual CommonAPI::Proxy {
public:
COMMONAPI_EXPORT DBusProxyBase(const DBusAddress &_address,
@@ -39,6 +39,11 @@ public:
COMMONAPI_EXPORT DBusMessage createMethodCall(const std::string &_method,
const std::string &_signature = "") const;
+ typedef std::function<void(const AvailabilityStatus, const Timeout_t remaining)> isAvailableAsyncCallback;
+ COMMONAPI_EXPORT virtual std::future<AvailabilityStatus> isAvailableAsync(
+ isAvailableAsyncCallback _callback,
+ const CallInfo *_info) const = 0;
+
COMMONAPI_EXPORT virtual DBusProxyConnection::DBusSignalHandlerToken addSignalMemberHandler(
const std::string &objectPath,
const std::string &interfaceName,
diff --git a/include/CommonAPI/DBus/DBusProxyConnection.hpp b/include/CommonAPI/DBus/DBusProxyConnection.hpp
index bec052b..8f7a1c8 100644
--- a/include/CommonAPI/DBus/DBusProxyConnection.hpp
+++ b/include/CommonAPI/DBus/DBusProxyConnection.hpp
@@ -57,19 +57,22 @@ class DBusProxyConnection {
virtual void unlock() = 0;
};
+ class DBusSignalHandler;
+
+ // 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 DBusSignalHandlerPath DBusSignalHandlerToken;
+
class DBusSignalHandler {
public:
virtual ~DBusSignalHandler() {}
virtual void onSignalDBusMessage(const DBusMessage&) = 0;
virtual void onInitialValueSignalDBusMessage(const DBusMessage&, const uint32_t) {};
- virtual void onError(const CommonAPI::CallStatus status) { (void) status; };
+ virtual void onSpecificError(const CommonAPI::CallStatus, const uint32_t ) {};
+ virtual void setSubscriptionToken(const DBusSignalHandlerToken, const uint32_t) {};
};
- // 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 DBusSignalHandlerPath DBusSignalHandlerToken;
-
typedef Event<AvailabilityStatus> ConnectionStatusEvent;
virtual ~DBusProxyConnection() {}
@@ -98,13 +101,13 @@ class DBusProxyConnection {
DBusSignalHandler* dbusSignalHandler,
const bool justAddFilter = false) = 0;
- virtual DBusSignalHandlerToken subscribeForSelectiveBroadcast(bool& subscriptionAccepted,
- const std::string& objectPath,
+ virtual void subscribeForSelectiveBroadcast(const std::string& objectPath,
const std::string& interfaceName,
const std::string& interfaceMemberName,
const std::string& interfaceMemberSignature,
DBusSignalHandler* dbusSignalHandler,
- DBusProxy* callingProxy) = 0;
+ DBusProxy* callingProxy,
+ uint32_t tag) = 0;
virtual void unsubscribeFromSelectiveBroadcast(const std::string& eventName,
DBusProxyConnection::DBusSignalHandlerToken subscription,
@@ -134,7 +137,11 @@ class DBusProxyConnection {
virtual bool hasDispatchThread() = 0;
- virtual bool sendPendingSelectiveSubscription(DBusProxy* proxy, std::string methodName) = 0;
+ virtual void sendPendingSelectiveSubscription(DBusProxy* proxy, std::string methodName,
+ DBusSignalHandler* dbusSignalHandler, uint32_t tag) = 0;
+
+ virtual void pushDBusMessageReply(const DBusMessage& reply,
+ std::unique_ptr<DBusMessageReplyAsyncHandler> dbusMessageReplyAsyncHandler) = 0;
};
} // namespace DBus
diff --git a/include/CommonAPI/DBus/DBusProxyHelper.hpp b/include/CommonAPI/DBus/DBusProxyHelper.hpp
index ef468ee..cb5b942 100644
--- a/include/CommonAPI/DBus/DBusProxyHelper.hpp
+++ b/include/CommonAPI/DBus/DBusProxyHelper.hpp
@@ -172,13 +172,13 @@ struct DBusProxyHelper<In_<DBusInputStream, DBusOutputStream, InArgs_...>,
}
}
- template <typename DBusProxy_ = DBusProxy, typename AsyncCallback_>
+ template <typename DBusProxy_ = DBusProxy, typename DelegateFunction_>
static std::future<CallStatus> callMethodAsync(
- const DBusProxy_ &_proxy,
+ DBusProxy_ &_proxy,
DBusMessage &_message,
const CommonAPI::CallInfo *_info,
const InArgs_&... _in,
- AsyncCallback_ _callback,
+ DelegateFunction_ _function,
std::tuple<OutArgs_...> _out) {
if (sizeof...(InArgs_) > 0) {
DBusOutputStream output(_message);
@@ -193,51 +193,75 @@ struct DBusProxyHelper<In_<DBusInputStream, DBusOutputStream, InArgs_...>,
output.flush();
}
- return _proxy.getDBusConnection()->sendDBusMessageWithReplyAsync(
- _message,
- DBusProxyAsyncCallbackHandler<
- OutArgs_...
- >::create(std::move(_callback), _out),
- _info);
+ typename DBusProxyAsyncCallbackHandler<
+ DBusProxy, OutArgs_...
+ >::Delegate delegate(_proxy.shared_from_this(), _function);
+ auto dbusMessageReplyAsyncHandler = DBusProxyAsyncCallbackHandler<
+ DBusProxy, OutArgs_...
+ >::create(delegate, _out).release();
+
+ if(_proxy.isAvailable()) {
+ return _proxy.getDBusConnection()->sendDBusMessageWithReplyAsync(
+ _message,
+ std::unique_ptr<DBusProxyConnection::DBusMessageReplyAsyncHandler>(dbusMessageReplyAsyncHandler),
+ _info);
+ } else {
+ //async isAvailable call with timeout
+ _proxy.isAvailableAsync([&_proxy, _message, _info,
+ _out, dbusMessageReplyAsyncHandler, _function](
+ 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);
+ _proxy.getDBusConnection()->sendDBusMessageWithReplyAsync(
+ _message,
+ std::unique_ptr<DBusProxyConnection::DBusMessageReplyAsyncHandler>(dbusMessageReplyAsyncHandler),
+ &newInfo);
+ } else {
+ //create error message and push it directly to the connection
+ unsigned int dummySerial = 999;
+ _message.setSerial(dummySerial); //set dummy serial
+ DBusMessage errorMessage = _message.createMethodError(DBUS_ERROR_UNKNOWN_METHOD);
+ _proxy.getDBusConnection()->pushDBusMessageReply(errorMessage,
+ std::unique_ptr<DBusProxyConnection::DBusMessageReplyAsyncHandler>(dbusMessageReplyAsyncHandler));
+ }
+ }, _info);
+ return dbusMessageReplyAsyncHandler->getFuture();
+ }
}
- template <typename DBusProxy_ = DBusProxy, typename AsyncCallback_>
+ template <typename DBusProxy_ = DBusProxy, typename DelegateFunction_>
static std::future<CallStatus> callMethodAsync(
- const DBusProxy_ &_proxy,
+ DBusProxy_ &_proxy,
const DBusAddress &_address,
const std::string &_method,
const std::string &_signature,
const CommonAPI::CallInfo *_info,
const InArgs_&... _in,
- AsyncCallback_ _callback,
+ DelegateFunction_ _function,
std::tuple<OutArgs_...> _out) {
#ifndef WIN32
static std::mutex callMethodAsync_mutex_;
#endif
std::lock_guard<std::mutex> lock(callMethodAsync_mutex_);
- if (_proxy.isAvailable()) {
- DBusMessage message = DBusMessage::createMethodCall(_address, _method, _signature);
- return callMethodAsync(_proxy, message, _info, _in..., _callback, _out);
- } else {
- CallStatus status = CallStatus::NOT_AVAILABLE;
- callCallbackOnNotAvailable(_callback, typename make_sequence<sizeof...(OutArgs_)>::type(), _out);
-
- std::promise<CallStatus> promise;
- promise.set_value(status);
- return promise.get_future();
- }
+ DBusMessage message = DBusMessage::createMethodCall(_address, _method, _signature);
+ return callMethodAsync(_proxy, message, _info, _in..., _function, _out);
}
- template <typename DBusProxy_ = DBusProxy, typename AsyncCallback_>
+ template <typename DBusProxy_ = DBusProxy, typename DelegateFunction_>
static std::future<CallStatus> callMethodAsync(
- const DBusProxy_ &_proxy,
+ DBusProxy_ &_proxy,
const std::string &_interface,
const std::string &_method,
const std::string &_signature,
const CommonAPI::CallInfo *_info,
const InArgs_&... _in,
- AsyncCallback_ _callback,
+ DelegateFunction_ _function,
std::tuple<OutArgs_...> _out) {
DBusAddress itsAddress(_proxy.getDBusAddress());
itsAddress.setInterface(_interface);
@@ -245,43 +269,34 @@ struct DBusProxyHelper<In_<DBusInputStream, DBusOutputStream, InArgs_...>,
_proxy, itsAddress,
_method, _signature,
_info,
- _in..., _callback, _out);
+ _in..., _function,
+ _out);
}
- template <typename DBusProxy_ = DBusProxy, typename AsyncCallback_>
+ template <typename DBusProxy_ = DBusProxy, typename DelegateFunction_>
static std::future<CallStatus> callMethodAsync(
- const DBusProxy_ &_proxy,
+ DBusProxy_ &_proxy,
const std::string &_method,
const std::string &_signature,
const CommonAPI::CallInfo *_info,
const InArgs_&... _in,
- AsyncCallback_ _callback,
+ DelegateFunction_ _function,
std::tuple<OutArgs_...> _out) {
#ifndef WIN32
static std::mutex callMethodAsync_mutex_;
#endif
std::lock_guard<std::mutex> lock(callMethodAsync_mutex_);
- if (_proxy.isAvailable()) {
- DBusMessage message = _proxy.createMethodCall(_method, _signature);
- return callMethodAsync(_proxy, message, _info, _in..., _callback, _out);
- } else {
- callCallbackOnNotAvailable(
- _callback, typename make_sequence<sizeof...(OutArgs_)>::type(), _out);
-
- CallStatus status = CallStatus::NOT_AVAILABLE;
- std::promise<CallStatus> promise;
- promise.set_value(status);
- return promise.get_future();
- }
+ DBusMessage message = _proxy.createMethodCall(_method, _signature);
+ return callMethodAsync(_proxy, message, _info, _in..., _function, _out);
}
template <int... ArgIndices_>
static void callCallbackOnNotAvailable(std::function<void(CallStatus, OutArgs_&...)> _callback,
index_sequence<ArgIndices_...>, std::tuple<OutArgs_...> _out) {
const CallStatus status(CallStatus::NOT_AVAILABLE);
- _callback(status, std::get<ArgIndices_>(_out)...);
- (void)_out;
+ _callback(status, std::get<ArgIndices_>(_out)...);
+ (void)_out;
}
};
diff --git a/include/CommonAPI/DBus/DBusProxyManager.hpp b/include/CommonAPI/DBus/DBusProxyManager.hpp
index 9540ead..ff28a26 100644
--- a/include/CommonAPI/DBus/DBusProxyManager.hpp
+++ b/include/CommonAPI/DBus/DBusProxyManager.hpp
@@ -26,7 +26,7 @@
namespace CommonAPI {
namespace DBus {
-class DBusProxyManager: public ProxyManager {
+class COMMONAPI_EXPORT_CLASS_EXPLICIT DBusProxyManager: public ProxyManager {
public:
COMMONAPI_EXPORT DBusProxyManager(DBusProxy &_proxy,
const std::string &_interfaceName);
diff --git a/include/CommonAPI/DBus/DBusSelectiveEvent.hpp b/include/CommonAPI/DBus/DBusSelectiveEvent.hpp
index 961063a..627a17b 100644
--- a/include/CommonAPI/DBus/DBusSelectiveEvent.hpp
+++ b/include/CommonAPI/DBus/DBusSelectiveEvent.hpp
@@ -36,21 +36,24 @@ public:
virtual ~DBusSelectiveEvent() {}
- virtual void onError(const CommonAPI::CallStatus status) {
- this->notifyError(status);
+ virtual void onSpecificError(const CommonAPI::CallStatus status, uint32_t tag) {
+ this->notifySpecificError(tag, status);
+ }
+
+ virtual void setSubscriptionToken(const DBusProxyConnection::DBusSignalHandlerToken _subscriptionToken, uint32_t tag) {
+ this->subscription_ = _subscriptionToken;
+ static_cast<DBusProxy&>(this->proxy_).insertSelectiveSubscription(this->name_, this, tag);
}
protected:
void onFirstListenerAdded(const Listener &) {
- bool success;
- this->subscription_
- = static_cast<DBusProxy&>(this->proxy_).subscribeForSelectiveBroadcastOnConnection(
- success, this->path_, this->interface_, this->name_, this->signature_, this);
-
- if (success == false) {
- // Call error listener with an error code
- this->notifyError(CommonAPI::CallStatus::SUBSCRIPTION_REFUSED);
- }
+
+ }
+
+ 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);
}
void onLastListenerRemoved(const Listener &) {
diff --git a/include/CommonAPI/DBus/DBusServiceRegistry.hpp b/include/CommonAPI/DBus/DBusServiceRegistry.hpp
index 584c47a..17e7139 100644
--- a/include/CommonAPI/DBus/DBusServiceRegistry.hpp
+++ b/include/CommonAPI/DBus/DBusServiceRegistry.hpp
@@ -68,6 +68,7 @@ class DBusServiceRegistry: public std::enable_shared_from_this<DBusServiceRegist
typedef DBusManagedInterfaceListenerList::iterator DBusManagedInterfaceSubscription;
static std::shared_ptr<DBusServiceRegistry> get(std::shared_ptr<DBusProxyConnection> _connection);
+ static void remove(std::shared_ptr<DBusProxyConnection> _connection);
DBusServiceRegistry(std::shared_ptr<DBusProxyConnection> dbusProxyConnection);
@@ -158,6 +159,7 @@ class DBusServiceRegistry: public std::enable_shared_from_this<DBusServiceRegist
: referenceCount(other.referenceCount),
state(other.state),
promiseOnResolve(std::move(other.promiseOnResolve)),
+ futureOnResolve(std::move(other.futureOnResolve)),
serviceName(std::move(other.serviceName)),
dbusInterfaceNamesCache(std::move(other.dbusInterfaceNamesCache)){
}
@@ -167,6 +169,7 @@ class DBusServiceRegistry: public std::enable_shared_from_this<DBusServiceRegist
size_t referenceCount;
DBusRecordState state;
std::promise<DBusRecordState> promiseOnResolve;
+ std::shared_future<DBusRecordState> futureOnResolve;
std::string serviceName;
std::unordered_set<std::string> dbusInterfaceNamesCache;
diff --git a/include/CommonAPI/DBus/DBusStubAdapter.hpp b/include/CommonAPI/DBus/DBusStubAdapter.hpp
index b2bea37..710277b 100644
--- a/include/CommonAPI/DBus/DBusStubAdapter.hpp
+++ b/include/CommonAPI/DBus/DBusStubAdapter.hpp
@@ -22,7 +22,7 @@ namespace DBus {
class DBusProxyConnection;
-class DBusStubAdapter
+class COMMONAPI_EXPORT_CLASS_EXPLICIT DBusStubAdapter
: virtual public CommonAPI::StubAdapter,
public DBusInterfaceHandler {
public:
diff --git a/include/CommonAPI/DBus/DBusStubAdapterHelper.hpp b/include/CommonAPI/DBus/DBusStubAdapterHelper.hpp
index 0084360..42d7301 100644
--- a/include/CommonAPI/DBus/DBusStubAdapterHelper.hpp
+++ b/include/CommonAPI/DBus/DBusStubAdapterHelper.hpp
@@ -108,8 +108,12 @@ class DBusStubAdapterHelper: public virtual DBusStubAdapter {
const char* interfaceMemberName = dbusMessage.getMember();
const char* interfaceMemberSignature = dbusMessage.getSignature();
- assert(interfaceMemberName);
- assert(interfaceMemberSignature);
+ if (NULL == interfaceMemberName) {
+ COMMONAPI_ERROR(std::string(__FUNCTION__), " member empty");
+ }
+ if (NULL == interfaceMemberSignature) {
+ COMMONAPI_ERROR(std::string(__FUNCTION__), " signature empty");
+ }
DBusInterfaceMemberPath dbusInterfaceMemberPath(interfaceMemberName, interfaceMemberSignature);
auto findIterator = getStubDispatcherTable().find(dbusInterfaceMemberPath);
@@ -160,8 +164,12 @@ class DBusStubAdapterHelper: public virtual DBusStubAdapter {
}
StubDispatcher* getterDispatcher = static_cast<StubDispatcher*>(attributeDispatcherIterator->second.getter);
- assert(getterDispatcher != NULL); // all attributes have at least a getter
- return (getterDispatcher->dispatchDBusMessage(_message, stub_, *this));
+ if (NULL == getterDispatcher) { // all attributes have at least a getter
+ COMMONAPI_ERROR(std::string(__FUNCTION__), "getterDispatcher == NULL");
+ return false;
+ } else {
+ return (getterDispatcher->dispatchDBusMessage(_message, stub_, *this));
+ }
}
bool handleFreedesktopSet(const DBusMessage& dbusMessage, DBusInputStream& dbusInputStream) {
@@ -206,10 +214,14 @@ class DBusStubAdapterHelper: public virtual DBusStubAdapter {
//To prevent the destruction of the stub whilst still handling a message
if (stub_) {
StubDispatcher* getterDispatcher = static_cast<StubDispatcher*>(attributeDispatcherIterator->second.getter);
- assert(getterDispatcher != NULL); // all attributes have at least a getter
- dbusOutputStream.align(8);
- dbusOutputStream << attributeDispatcherIterator->first;
- getterDispatcher->appendGetAllReply(dbusMessage, stub_, *this, dbusOutputStream);
+ if (NULL == getterDispatcher) { // all attributes have at least a getter
+ COMMONAPI_ERROR(std::string(__FUNCTION__), "getterDispatcher == NULL");
+ break;
+ } else {
+ dbusOutputStream.align(8);
+ dbusOutputStream << attributeDispatcherIterator->first;
+ getterDispatcher->appendGetAllReply(dbusMessage, stub_, *this, dbusOutputStream);
+ }
}
}
@@ -463,9 +475,14 @@ private:
}
output.flush();
}
- bool isSuccessful = connection_->sendDBusMessage(reply->second);
- pending_.erase(_call);
- return isSuccessful;
+ if (std::shared_ptr<DBusProxyConnection> connection = connection_.lock()) {
+ bool isSuccessful = connection->sendDBusMessage(reply->second);
+ pending_.erase(_call);
+ return isSuccessful;
+ }
+ else {
+ return false;
+ }
}
return false;
}
@@ -479,7 +496,7 @@ private:
std::map<CommonAPI::CallId_t, DBusMessage> pending_;
std::mutex mutex_; // protects pending_
- std::shared_ptr<DBusProxyConnection> connection_;
+ std::weak_ptr<DBusProxyConnection> connection_;
};
template< class, class, class, class >
diff --git a/include/murmurhash/MurmurHash3.h b/include/murmurhash/MurmurHash3.h
index 54e9d3f..a7e45a7 100644
--- a/include/murmurhash/MurmurHash3.h
+++ b/include/murmurhash/MurmurHash3.h
@@ -8,9 +8,9 @@
//-----------------------------------------------------------------------------
// Platform-specific functions and macros
-// Microsoft Visual Studio
+// Microsoft Visual Studio before VS2010
-#if defined(_MSC_VER)
+#if defined(_MSC_VER) && (_MSC_VER < 1600)
typedef unsigned char uint8_t;
typedef unsigned long uint32_t;
@@ -18,11 +18,11 @@ typedef unsigned __int64 uint64_t;
// Other compilers
-#else // defined(_MSC_VER)
+#else // defined(_MSC_VER) && (_MSC_VER < 1600)
#include <stdint.h>
-#endif // !defined(_MSC_VER)
+#endif // defined(_MSC_VER) && (_MSC_VER < 1600)
//-----------------------------------------------------------------------------