summaryrefslogtreecommitdiff
path: root/include/CommonAPI/DBus/DBusProxyAsyncCallbackHandler.hpp
diff options
context:
space:
mode:
Diffstat (limited to 'include/CommonAPI/DBus/DBusProxyAsyncCallbackHandler.hpp')
-rw-r--r--include/CommonAPI/DBus/DBusProxyAsyncCallbackHandler.hpp152
1 files changed, 117 insertions, 35 deletions
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