Introduce support for cancellable async calls

This commit is contained in:
sangelovic
2020-03-29 21:43:20 +02:00
committed by Stanislav Angelovič
parent e91bedd4cb
commit 00d0837d98
9 changed files with 174 additions and 34 deletions

View File

@ -42,6 +42,7 @@ namespace sdbus {
class IProxy;
class Variant;
class Error;
class PendingAsyncCall;
}
namespace sdbus {
@ -193,7 +194,7 @@ namespace sdbus {
template <typename _Rep, typename _Period>
AsyncMethodInvoker& withTimeout(const std::chrono::duration<_Rep, _Period>& timeout);
template <typename... _Args> AsyncMethodInvoker& withArguments(_Args&&... args);
template <typename _Function> void uponReplyInvoke(_Function&& callback);
template <typename _Function> PendingAsyncCall uponReplyInvoke(_Function&& callback);
private:
IProxy& proxy_;

View File

@ -576,7 +576,7 @@ namespace sdbus {
}
template <typename _Function>
void AsyncMethodInvoker::uponReplyInvoke(_Function&& callback)
PendingAsyncCall AsyncMethodInvoker::uponReplyInvoke(_Function&& callback)
{
assert(method_.isValid()); // onInterface() must be placed/called prior to this function
@ -594,7 +594,7 @@ namespace sdbus {
sdbus::apply(callback, error, args);
};
proxy_.callMethod(method_, std::move(asyncReplyHandler), timeout_);
return proxy_.callMethod(method_, std::move(asyncReplyHandler), timeout_);
}
/*** ---------------- ***/

View File

@ -38,6 +38,10 @@ namespace sdbus {
class MethodCall;
class MethodReply;
class IConnection;
class PendingAsyncCall;
namespace internal {
class Proxy;
}
}
namespace sdbus {
@ -108,6 +112,7 @@ namespace sdbus {
* @param[in] message Message representing an async method call
* @param[in] asyncReplyCallback Handler for the async reply
* @param[in] timeout Timeout for dbus call in microseconds
* @return Cookie for the the pending asynchronous call
*
* The call is non-blocking. It doesn't wait for the reply. Once the reply arrives,
* the provided async reply handler will get invoked from the context of the connection
@ -117,7 +122,7 @@ namespace sdbus {
*
* @throws sdbus::Error in case of failure
*/
virtual void callMethod(const MethodCall& message, async_reply_handler asyncReplyCallback, uint64_t timeout = 0) = 0;
virtual PendingAsyncCall callMethod(const MethodCall& message, async_reply_handler asyncReplyCallback, uint64_t timeout = 0) = 0;
/*!
* @copydoc IProxy::callMethod(const MethodCall&,async_reply_handler,uint64_t)
@ -263,6 +268,46 @@ namespace sdbus {
[[nodiscard]] PropertySetter setProperty(const std::string& propertyName);
};
/********************************************//**
* @class PendingAsyncCall
*
* PendingAsyncCall represents a simple handle type to cancel the delivery
* of the asynchronous D-Bus call result to the application.
*
* The handle is lifetime-independent from the originating Proxy object.
* It's safe to call its methods even after the Proxy has gone.
*
***********************************************/
class PendingAsyncCall
{
public:
/*!
* @brief Cancels the delivery of the pending asynchronous call result
*
* This function effectively removes the callback handler registered to the
* async D-Bus method call result delivery. Does nothing if the call was
* completed already, or if the originating Proxy object has gone meanwhile.
*/
void cancel();
/*!
* @brief Answers whether the asynchronous call is still pending
*
* @return True if the call is pending, false if the call has been fully completed
*
* Pending call in this context means a call whose results have not arrived, or
* have arrived and are currently being processed by the callback handler.
*/
bool isPending() const;
private:
friend internal::Proxy;
PendingAsyncCall(std::weak_ptr<void> callData);
private:
std::weak_ptr<void> callData_;
};
// Out-of-line member definitions
template <typename _Rep, typename _Period>