feat: add support for async registration of matches (#374)

This commit is contained in:
Stanislav Angelovič
2023-11-03 17:57:52 +01:00
committed by GitHub
parent 9da18aec25
commit 9490b3351f
9 changed files with 131 additions and 15 deletions

View File

@@ -217,17 +217,11 @@ uint64_t Connection::getMethodCallTimeout() const
Slot Connection::addMatch(const std::string& match, message_handler callback)
{
auto matchInfo = std::make_unique<MatchInfo>(MatchInfo{std::move(callback), *this, {}});
SDBUS_THROW_ERROR_IF(!callback, "Invalid match callback handler provided", EINVAL);
auto messageHandler = [](sd_bus_message *sdbusMessage, void *userData, sd_bus_error */*retError*/) -> int
{
auto* matchInfo = static_cast<MatchInfo*>(userData);
auto message = Message::Factory::create<PlainMessage>(sdbusMessage, &matchInfo->connection.getSdBusInterface());
matchInfo->callback(message);
return 0;
};
auto matchInfo = std::make_unique<MatchInfo>(MatchInfo{std::move(callback), {}, *this, {}});
auto r = iface_->sd_bus_add_match(bus_.get(), &matchInfo->slot, match.c_str(), std::move(messageHandler), matchInfo.get());
auto r = iface_->sd_bus_add_match(bus_.get(), &matchInfo->slot, match.c_str(), &Connection::sdbus_match_callback, matchInfo.get());
SDBUS_THROW_ERROR_IF(r < 0, "Failed to add match", -r);
return {matchInfo.release(), [this](void *ptr)
@@ -243,6 +237,34 @@ void Connection::addMatch(const std::string& match, message_handler callback, fl
floatingMatchRules_.push_back(addMatch(match, std::move(callback)));
}
Slot Connection::addMatchAsync(const std::string& match, message_handler callback, message_handler installCallback)
{
SDBUS_THROW_ERROR_IF(!callback, "Invalid match callback handler provided", EINVAL);
sd_bus_message_handler_t sdbusInstallCallback = installCallback ? &Connection::sdbus_match_install_callback : nullptr;
auto matchInfo = std::make_unique<MatchInfo>(MatchInfo{std::move(callback), std::move(installCallback), *this, {}});
auto r = iface_->sd_bus_add_match_async( bus_.get()
, &matchInfo->slot
, match.c_str()
, &Connection::sdbus_match_callback
, sdbusInstallCallback
, matchInfo.get());
SDBUS_THROW_ERROR_IF(r < 0, "Failed to add match", -r);
return {matchInfo.release(), [this](void *ptr)
{
auto* matchInfo = static_cast<MatchInfo*>(ptr);
iface_->sd_bus_slot_unref(matchInfo->slot);
std::default_delete<MatchInfo>{}(matchInfo);
}};
}
void Connection::addMatchAsync(const std::string& match, message_handler callback, message_handler installCallback, floating_slot_t)
{
floatingMatchRules_.push_back(addMatchAsync(match, std::move(callback), std::move(installCallback)));
}
Slot Connection::addObjectVTable( const std::string& objectPath
, const std::string& interfaceName
, const sd_bus_vtable* vtable
@@ -565,6 +587,22 @@ std::vector</*const */char*> Connection::to_strv(const std::vector<std::string>&
return strv;
}
int Connection::sdbus_match_callback(sd_bus_message *sdbusMessage, void *userData, sd_bus_error */*retError*/)
{
auto* matchInfo = static_cast<MatchInfo*>(userData);
auto message = Message::Factory::create<PlainMessage>(sdbusMessage, &matchInfo->connection.getSdBusInterface());
matchInfo->callback(message);
return 0;
}
int Connection::sdbus_match_install_callback(sd_bus_message *sdbusMessage, void *userData, sd_bus_error */*retError*/)
{
auto* matchInfo = static_cast<MatchInfo*>(userData);
auto message = Message::Factory::create<PlainMessage>(sdbusMessage, &matchInfo->connection.getSdBusInterface());
matchInfo->installCallback(message);
return 0;
}
Connection::EventFd::EventFd()
{
fd = eventfd(0, EFD_CLOEXEC | EFD_NONBLOCK);