From d47e9d1834cedd4608f47d9ba5bc3ed4712d3578 Mon Sep 17 00:00:00 2001 From: riuriuriu Date: Tue, 30 Mar 2021 11:42:58 +0200 Subject: [PATCH] fix issue 145, signals are not filtered by sender --- src/Connection.cpp | 15 ++++++++++----- src/Connection.h | 9 +++++---- src/IConnection.h | 3 ++- src/Proxy.cpp | 3 ++- 4 files changed, 19 insertions(+), 11 deletions(-) diff --git a/src/Connection.cpp b/src/Connection.cpp index 166f1ee..847dd66 100644 --- a/src/Connection.cpp +++ b/src/Connection.cpp @@ -289,7 +289,8 @@ void Connection::emitInterfacesRemovedSignal( const std::string& objectPath SDBUS_THROW_ERROR_IF(r < 0, "Failed to emit InterfacesRemoved signal", -r); } -SlotPtr Connection::registerSignalHandler( const std::string& objectPath +SlotPtr Connection::registerSignalHandler( const std::string& sender + , const std::string& objectPath , const std::string& interfaceName , const std::string& signalName , sd_bus_message_handler_t callback @@ -297,7 +298,9 @@ SlotPtr Connection::registerSignalHandler( const std::string& objectPath { sd_bus_slot *slot{}; - auto filter = composeSignalMatchFilter(objectPath, interfaceName, signalName); + // alternatively to our own composeSignalMatchFilter() implementation, we could also use sd_bus_match_signal() from + // https://www.freedesktop.org/software/systemd/man/sd_bus_add_match.html# + auto filter = composeSignalMatchFilter(sender, objectPath, interfaceName, signalName); auto r = iface_->sd_bus_add_match(bus_.get(), &slot, filter.c_str(), callback, userData); SDBUS_THROW_ERROR_IF(r < 0, "Failed to register signal handler", -r); @@ -417,13 +420,15 @@ bool Connection::waitForNextRequest() return true; } -std::string Connection::composeSignalMatchFilter( const std::string& objectPath - , const std::string& interfaceName - , const std::string& signalName ) + std::string Connection::composeSignalMatchFilter(const std::string &sender, + const std::string &objectPath, + const std::string &interfaceName, + const std::string &signalName) { std::string filter; filter += "type='signal',"; + filter += "sender='" + sender + "',"; filter += "interface='" + interfaceName + "',"; filter += "member='" + signalName + "',"; filter += "path='" + objectPath + "'"; diff --git a/src/Connection.h b/src/Connection.h index d171ef6..8539bad 100644 --- a/src/Connection.h +++ b/src/Connection.h @@ -99,7 +99,8 @@ namespace sdbus::internal { void emitInterfacesRemovedSignal( const std::string& objectPath , const std::vector& interfaces ) override; - SlotPtr registerSignalHandler( const std::string& objectPath + SlotPtr registerSignalHandler( const std::string& sender + , const std::string& objectPath , const std::string& interfaceName , const std::string& signalName , sd_bus_message_handler_t callback @@ -115,9 +116,9 @@ namespace sdbus::internal { BusPtr openBus(const std::function& busFactory); void finishHandshake(sd_bus* bus); bool waitForNextRequest(); - static std::string composeSignalMatchFilter( const std::string& objectPath - , const std::string& interfaceName - , const std::string& signalName ); + static std::string composeSignalMatchFilter(const std::string &sender, const std::string &objectPath, + const std::string &interfaceName, + const std::string &signalName); void notifyEventLoopToExit(); void clearExitNotification(); void joinWithEventLoop(); diff --git a/src/IConnection.h b/src/IConnection.h index 37b3aaa..754486a 100644 --- a/src/IConnection.h +++ b/src/IConnection.h @@ -82,7 +82,8 @@ namespace sdbus::internal { [[nodiscard]] virtual SlotPtr addObjectManager(const std::string& objectPath, void* /*dummy*/ = nullptr) = 0; - [[nodiscard]] virtual SlotPtr registerSignalHandler( const std::string& objectPath + [[nodiscard]] virtual SlotPtr registerSignalHandler( const std::string& sender + , const std::string& objectPath , const std::string& interfaceName , const std::string& signalName , sd_bus_message_handler_t callback diff --git a/src/Proxy.cpp b/src/Proxy.cpp index 25665f8..f621781 100644 --- a/src/Proxy.cpp +++ b/src/Proxy.cpp @@ -183,7 +183,8 @@ void Proxy::registerSignalHandlers(sdbus::internal::IConnection& connection) { const auto& signalName = signalItem.first; auto& slot = signalItem.second.slot_; - slot = connection.registerSignalHandler( objectPath_ + slot = connection.registerSignalHandler( destination_ + , objectPath_ , interfaceName , signalName , &Proxy::sdbus_signal_handler