forked from Kistler-Group/sdbus-cpp
Force event loop to re-enter processing to handle queued messages
This commit is contained in:
@ -64,6 +64,10 @@ namespace sdbus {
|
|||||||
*/
|
*/
|
||||||
struct PollData
|
struct PollData
|
||||||
{
|
{
|
||||||
|
/*!
|
||||||
|
* The read fd to be monitored by the event loop.
|
||||||
|
*/
|
||||||
|
int event_fd;
|
||||||
/*!
|
/*!
|
||||||
* The read fd to be monitored by the event loop.
|
* The read fd to be monitored by the event loop.
|
||||||
*/
|
*/
|
||||||
|
@ -75,11 +75,16 @@ Connection::Connection(std::unique_ptr<ISdBus>&& interface, pseudo_bus_t)
|
|||||||
, bus_(openPseudoBus())
|
, bus_(openPseudoBus())
|
||||||
{
|
{
|
||||||
assert(iface_ != nullptr);
|
assert(iface_ != nullptr);
|
||||||
|
eventFd_.fd = eventfd(0, 0);
|
||||||
|
assert(eventFd_.fd >= 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
Connection::~Connection()
|
Connection::~Connection()
|
||||||
{
|
{
|
||||||
Connection::leaveEventLoop();
|
Connection::leaveEventLoop();
|
||||||
|
if (0 <= eventFd_.fd) {
|
||||||
|
close(eventFd_.fd);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Connection::requestName(const std::string& name)
|
void Connection::requestName(const std::string& name)
|
||||||
@ -141,7 +146,7 @@ Connection::PollData Connection::getEventLoopPollData() const
|
|||||||
auto r = iface_->sd_bus_get_poll_data(bus_.get(), &pollData);
|
auto r = iface_->sd_bus_get_poll_data(bus_.get(), &pollData);
|
||||||
SDBUS_THROW_ERROR_IF(r < 0, "Failed to get bus poll data", -r);
|
SDBUS_THROW_ERROR_IF(r < 0, "Failed to get bus poll data", -r);
|
||||||
|
|
||||||
return {pollData.fd, pollData.events, pollData.timeout_usec};
|
return {eventFd_.fd, pollData.fd, pollData.events, pollData.timeout_usec};
|
||||||
}
|
}
|
||||||
|
|
||||||
const ISdBus& Connection::getSdBusInterface() const
|
const ISdBus& Connection::getSdBusInterface() const
|
||||||
@ -445,6 +450,11 @@ void Connection::notifyEventLoopToExit() const
|
|||||||
notifyEventLoop(loopExitFd_.fd);
|
notifyEventLoop(loopExitFd_.fd);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Connection::notifyEventLoop() const
|
||||||
|
{
|
||||||
|
notifyEventLoop(eventFd_.fd);
|
||||||
|
}
|
||||||
|
|
||||||
void Connection::notifyEventLoopNewTimeout() const
|
void Connection::notifyEventLoopNewTimeout() const
|
||||||
{
|
{
|
||||||
// The extra notifications for new timeouts are only needed if calls are made asynchronously to the event loop.
|
// The extra notifications for new timeouts are only needed if calls are made asynchronously to the event loop.
|
||||||
|
@ -139,6 +139,7 @@ namespace sdbus::internal {
|
|||||||
void notifyEventLoop(int fd) const;
|
void notifyEventLoop(int fd) const;
|
||||||
void notifyEventLoopToExit() const;
|
void notifyEventLoopToExit() const;
|
||||||
void clearEventLoopNotification(int fd) const;
|
void clearEventLoopNotification(int fd) const;
|
||||||
|
void notifyEventLoop() const override;
|
||||||
void notifyEventLoopNewTimeout() const override;
|
void notifyEventLoopNewTimeout() const override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -90,6 +90,7 @@ namespace sdbus::internal {
|
|||||||
, sd_bus_message_handler_t callback
|
, sd_bus_message_handler_t callback
|
||||||
, void* userData ) = 0;
|
, void* userData ) = 0;
|
||||||
|
|
||||||
|
virtual void notifyEventLoop() const = 0;
|
||||||
virtual void notifyEventLoopNewTimeout() const = 0;
|
virtual void notifyEventLoopNewTimeout() const = 0;
|
||||||
virtual MethodReply tryCallMethodSynchronously(const MethodCall& message, uint64_t timeout) = 0;
|
virtual MethodReply tryCallMethodSynchronously(const MethodCall& message, uint64_t timeout) = 0;
|
||||||
};
|
};
|
||||||
|
@ -782,6 +782,10 @@ MethodReply MethodCall::sendWithReply(uint64_t timeout) const
|
|||||||
|
|
||||||
SDBUS_THROW_ERROR_IF(r < 0, "Failed to call method", -r);
|
SDBUS_THROW_ERROR_IF(r < 0, "Failed to call method", -r);
|
||||||
|
|
||||||
|
// Force event loop to re-enter processing to handle queued messages
|
||||||
|
SDBUS_THROW_ERROR_IF(connection_ == nullptr, "Invalid use of MethodCall API", ENOTSUP);
|
||||||
|
connection_->notifyEventLoop();
|
||||||
|
|
||||||
return Factory::create<MethodReply>(sdbusReply, sdbus_, adopt_message);
|
return Factory::create<MethodReply>(sdbusReply, sdbus_, adopt_message);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -790,6 +794,10 @@ MethodReply MethodCall::sendWithNoReply() const
|
|||||||
auto r = sdbus_->sd_bus_send(nullptr, (sd_bus_message*)msg_, nullptr);
|
auto r = sdbus_->sd_bus_send(nullptr, (sd_bus_message*)msg_, nullptr);
|
||||||
SDBUS_THROW_ERROR_IF(r < 0, "Failed to call method with no reply", -r);
|
SDBUS_THROW_ERROR_IF(r < 0, "Failed to call method with no reply", -r);
|
||||||
|
|
||||||
|
// Force event loop to re-enter processing to handle queued messages
|
||||||
|
SDBUS_THROW_ERROR_IF(connection_ == nullptr, "Invalid use of MethodCall API", ENOTSUP);
|
||||||
|
connection_->notifyEventLoop();
|
||||||
|
|
||||||
return Factory::create<MethodReply>(); // No reply
|
return Factory::create<MethodReply>(); // No reply
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user