Fix issue of event loop thread and synchronous method call thread polling on the same D-Bus connection

Synchronous D-Bus method calls are now done in terms of blocking asynchronous calls.
This commit is contained in:
sangelovic
2020-01-12 13:10:34 +01:00
parent 5121d46eed
commit f41d9bc395
17 changed files with 281 additions and 82 deletions

View File

@ -192,7 +192,7 @@ namespace sdbus {
IProxy& proxy_;
const std::string& methodName_;
uint64_t timeout_{};
AsyncMethodCall method_;
MethodCall method_;
};
class SignalSubscriber

View File

@ -503,7 +503,7 @@ namespace sdbus {
inline AsyncMethodInvoker& AsyncMethodInvoker::onInterface(const std::string& interfaceName)
{
method_ = proxy_.createAsyncMethodCall(interfaceName, methodName_);
method_ = proxy_.createMethodCall(interfaceName, methodName_);
return *this;
}

View File

@ -36,7 +36,6 @@
// Forward declarations
namespace sdbus {
class MethodCall;
class AsyncMethodCall;
class MethodReply;
class IConnection;
}
@ -77,21 +76,6 @@ namespace sdbus {
*/
virtual MethodCall createMethodCall(const std::string& interfaceName, const std::string& methodName) = 0;
/*!
* @brief Creates an asynchronous method call message
*
* @param[in] interfaceName Name of an interface that provides a given method
* @param[in] methodName Name of the method
* @return A method call message
*
* Serialize method arguments into the returned message and invoke the method by passing
* the message with serialized arguments to the @c callMethod function.
* Alternatively, use higher-level API @c callMethodAsync(const std::string& methodName) defined below.
*
* @throws sdbus::Error in case of failure
*/
virtual AsyncMethodCall createAsyncMethodCall(const std::string& interfaceName, const std::string& methodName) = 0;
/*!
* @brief Calls method on the proxied D-Bus object
*
@ -133,13 +117,13 @@ namespace sdbus {
*
* @throws sdbus::Error in case of failure
*/
virtual void callMethod(const AsyncMethodCall& message, async_reply_handler asyncReplyCallback, uint64_t timeout = 0) = 0;
virtual void callMethod(const MethodCall& message, async_reply_handler asyncReplyCallback, uint64_t timeout = 0) = 0;
/*!
* @copydoc IProxy::callMethod(const AsyncMethodCall&,async_reply_handler,uint64_t)
* @copydoc IProxy::callMethod(const MethodCall&,async_reply_handler,uint64_t)
*/
template <typename _Rep, typename _Period>
void callMethod(const AsyncMethodCall& message, async_reply_handler asyncReplyCallback, const std::chrono::duration<_Rep, _Period>& timeout);
void callMethod(const MethodCall& message, async_reply_handler asyncReplyCallback, const std::chrono::duration<_Rep, _Period>& timeout);
/*!
* @brief Registers a handler for the desired signal emitted by the proxied D-Bus object
@ -289,7 +273,7 @@ namespace sdbus {
}
template <typename _Rep, typename _Period>
inline void IProxy::callMethod(const AsyncMethodCall& message, async_reply_handler asyncReplyCallback, const std::chrono::duration<_Rep, _Period>& timeout)
inline void IProxy::callMethod(const MethodCall& message, async_reply_handler asyncReplyCallback, const std::chrono::duration<_Rep, _Period>& timeout)
{
auto microsecs = std::chrono::duration_cast<std::chrono::microseconds>(timeout);
callMethod(message, std::move(asyncReplyCallback), microsecs.count());

View File

@ -165,35 +165,32 @@ namespace sdbus {
mutable bool ok_{true};
};
struct dont_request_slot_t { explicit dont_request_slot_t() = default; };
inline constexpr dont_request_slot_t dont_request_slot{};
class MethodCall : public Message
{
using Message::Message;
friend Factory;
public:
MethodCall() = default;
MethodReply send(uint64_t timeout = 0) const;
MethodReply createReply() const;
MethodReply createErrorReply(const sdbus::Error& error) const;
void dontExpectReply();
bool doesntExpectReply() const;
private:
MethodReply sendWithReply(uint64_t timeout) const;
MethodReply sendWithNoReply() const;
};
class AsyncMethodCall : public Message
{
using Message::Message;
friend Factory;
public:
using Slot = std::unique_ptr<void, std::function<void(void*)>>;
AsyncMethodCall() = default;
explicit AsyncMethodCall(MethodCall&& call) noexcept;
Slot send(void* callback, void* userData, uint64_t timeout = 0) const;
MethodCall() = default;
MethodReply send(uint64_t timeout) const;
void send(void* callback, void* userData, uint64_t timeout, dont_request_slot_t) const;
[[nodiscard]] Slot send(void* callback, void* userData, uint64_t timeout) const;
MethodReply createReply() const;
MethodReply createErrorReply(const sdbus::Error& error) const;
void dontExpectReply();
bool doesntExpectReply() const;
private:
MethodReply sendWithReply(uint64_t timeout = 0) const;
MethodReply sendWithNoReply() const;
};
class MethodReply : public Message