forked from Kistler-Group/sdbus-cpp
fix timeout handling * Despite what is documented in sd_bus_get_timeout(3), the timeout returned is actually an absolute time point of Linux's CLOCK_MONOTONIC clock. Hence, we first have to subtract the current time from the timeout in order to get a relative time that can be passed to poll. * For async call timeouts to reliably work, we need a way to notify the event loop of a connection that is currently blocked waiting in poll. I.e. assume the event loop thread entered poll with a timeout set to T1. Afterwards, the main thread starts an async call C with a timeout T2 < T1. In order for C to be canceled after its timeout T1 has elapsed, we have to be able to notify the event loop so that it can update its poll data. Co-authored-by: Urs Ritzmann <ursritzmann@protonmail.ch> Co-authored-by: Lukasz Marcul <lukasz.marcul@onemeter.com>
This commit is contained in:
co-authored by
Urs Ritzmann
Lukasz Marcul
parent
0b8f2d9752
commit
bb0f3f0242
@@ -737,6 +737,15 @@ std::string Message::getSELinuxContext() const
|
||||
return cLabel;
|
||||
}
|
||||
|
||||
|
||||
MethodCall::MethodCall(void *msg, internal::ISdBus *sdbus, const internal::IConnection *connection,
|
||||
adopt_message_t) noexcept
|
||||
: Message(msg, sdbus, adopt_message)
|
||||
, connection_(connection)
|
||||
{
|
||||
assert(connection_ != nullptr);
|
||||
}
|
||||
|
||||
void MethodCall::dontExpectReply()
|
||||
{
|
||||
auto r = sd_bus_message_set_expect_reply((sd_bus_message*)msg_, 0);
|
||||
@@ -771,6 +780,10 @@ MethodReply MethodCall::sendWithReply(uint64_t timeout) const
|
||||
|
||||
SDBUS_THROW_ERROR_IF(r < 0, "Failed to call method", -r);
|
||||
|
||||
if (connection_) {
|
||||
connection_->notifyEventLoopNewTimeout();
|
||||
}
|
||||
|
||||
return Factory::create<MethodReply>(sdbusReply, sdbus_, adopt_message);
|
||||
}
|
||||
|
||||
@@ -786,6 +799,9 @@ void MethodCall::send(void* callback, void* userData, uint64_t timeout, dont_req
|
||||
{
|
||||
auto r = sdbus_->sd_bus_call_async(nullptr, nullptr, (sd_bus_message*)msg_, (sd_bus_message_handler_t)callback, userData, timeout);
|
||||
SDBUS_THROW_ERROR_IF(r < 0, "Failed to call method", -r);
|
||||
if (connection_) {
|
||||
connection_->notifyEventLoopNewTimeout();
|
||||
}
|
||||
}
|
||||
|
||||
MethodCall::Slot MethodCall::send(void* callback, void* userData, uint64_t timeout) const
|
||||
@@ -794,6 +810,9 @@ MethodCall::Slot MethodCall::send(void* callback, void* userData, uint64_t timeo
|
||||
|
||||
auto r = sdbus_->sd_bus_call_async(nullptr, &slot, (sd_bus_message*)msg_, (sd_bus_message_handler_t)callback, userData, timeout);
|
||||
SDBUS_THROW_ERROR_IF(r < 0, "Failed to call method asynchronously", -r);
|
||||
if (connection_) {
|
||||
connection_->notifyEventLoopNewTimeout();
|
||||
}
|
||||
|
||||
return Slot{slot, [sdbus_ = sdbus_](void *slot){ sdbus_->sd_bus_slot_unref((sd_bus_slot*)slot); }};
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user