forked from Kistler-Group/sdbus-cpp
Fix #214: Add means to unregister signal handler
This commit is contained in:
committed by
Stanislav Angelovič
parent
442670ec18
commit
41d33117cc
@ -216,6 +216,17 @@ namespace sdbus {
|
|||||||
std::string interfaceName_;
|
std::string interfaceName_;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class SignalUnsubscriber
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
SignalUnsubscriber(IProxy& proxy, const std::string& signalName);
|
||||||
|
void onInterface(std::string interfaceName);
|
||||||
|
|
||||||
|
private:
|
||||||
|
IProxy& proxy_;
|
||||||
|
const std::string& signalName_;
|
||||||
|
};
|
||||||
|
|
||||||
class PropertyGetter
|
class PropertyGetter
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
@ -671,6 +671,21 @@ namespace sdbus {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*** ------------------ ***/
|
||||||
|
/*** SignalUnsubscriber ***/
|
||||||
|
/*** ------------------ ***/
|
||||||
|
|
||||||
|
inline SignalUnsubscriber::SignalUnsubscriber(IProxy& proxy, const std::string& signalName)
|
||||||
|
: proxy_(proxy)
|
||||||
|
, signalName_(signalName)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void SignalUnsubscriber::onInterface(std::string interfaceName)
|
||||||
|
{
|
||||||
|
proxy_.unregisterSignalHandler(interfaceName, signalName_);
|
||||||
|
}
|
||||||
|
|
||||||
/*** -------------- ***/
|
/*** -------------- ***/
|
||||||
/*** PropertyGetter ***/
|
/*** PropertyGetter ***/
|
||||||
/*** -------------- ***/
|
/*** -------------- ***/
|
||||||
|
@ -143,6 +143,17 @@ namespace sdbus {
|
|||||||
, const std::string& signalName
|
, const std::string& signalName
|
||||||
, signal_handler signalHandler ) = 0;
|
, signal_handler signalHandler ) = 0;
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* @brief Unregisters the handler of the desired signal
|
||||||
|
*
|
||||||
|
* @param[in] interfaceName Name of an interface that the signal belongs to
|
||||||
|
* @param[in] signalName Name of the signal
|
||||||
|
*
|
||||||
|
* @throws sdbus::Error in case of failure
|
||||||
|
*/
|
||||||
|
virtual void unregisterSignalHandler( const std::string& interfaceName
|
||||||
|
, const std::string& signalName ) = 0;
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* @brief Finishes the registration of signal handlers
|
* @brief Finishes the registration of signal handlers
|
||||||
*
|
*
|
||||||
@ -229,6 +240,23 @@ namespace sdbus {
|
|||||||
*/
|
*/
|
||||||
[[nodiscard]] SignalSubscriber uponSignal(const std::string& signalName);
|
[[nodiscard]] SignalSubscriber uponSignal(const std::string& signalName);
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* @brief Unregisters signal handler of a given signal of the proxied D-Bus object
|
||||||
|
*
|
||||||
|
* @param[in] signalName Name of the signal
|
||||||
|
* @return A helper object for convenient unregistration of the signal handler
|
||||||
|
*
|
||||||
|
* This is a high-level, convenience way of unregistering a D-Bus signal's handler.
|
||||||
|
*
|
||||||
|
* Example of use:
|
||||||
|
* @code
|
||||||
|
* object_.muteSignal("fooSignal").onInterface("com.kistler.foo");
|
||||||
|
* @endcode
|
||||||
|
*
|
||||||
|
* @throws sdbus::Error in case of failure
|
||||||
|
*/
|
||||||
|
[[nodiscard]] SignalUnsubscriber muteSignal(const std::string& signalName);
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* @brief Gets value of a property of the proxied D-Bus object
|
* @brief Gets value of a property of the proxied D-Bus object
|
||||||
*
|
*
|
||||||
@ -369,6 +397,11 @@ namespace sdbus {
|
|||||||
return SignalSubscriber(*this, signalName);
|
return SignalSubscriber(*this, signalName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline SignalUnsubscriber IProxy::muteSignal(const std::string& signalName)
|
||||||
|
{
|
||||||
|
return SignalUnsubscriber(*this, signalName);
|
||||||
|
}
|
||||||
|
|
||||||
inline PropertyGetter IProxy::getProperty(const std::string& propertyName)
|
inline PropertyGetter IProxy::getProperty(const std::string& propertyName)
|
||||||
{
|
{
|
||||||
return PropertyGetter(*this, propertyName);
|
return PropertyGetter(*this, propertyName);
|
||||||
|
@ -167,6 +167,16 @@ void Proxy::registerSignalHandler( const std::string& interfaceName
|
|||||||
SDBUS_THROW_ERROR_IF(!inserted, "Failed to register signal handler: handler already exists", EINVAL);
|
SDBUS_THROW_ERROR_IF(!inserted, "Failed to register signal handler: handler already exists", EINVAL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Proxy::unregisterSignalHandler( const std::string& interfaceName
|
||||||
|
, const std::string& signalName )
|
||||||
|
{
|
||||||
|
auto& interface = interfaces_[interfaceName];
|
||||||
|
|
||||||
|
auto removeResult = interface.signals_.erase(signalName);
|
||||||
|
|
||||||
|
SDBUS_THROW_ERROR_IF(removeResult == 0, "Failed to unregister signal handler: handler not exists", EINVAL);
|
||||||
|
}
|
||||||
|
|
||||||
void Proxy::finishRegistration()
|
void Proxy::finishRegistration()
|
||||||
{
|
{
|
||||||
registerSignalHandlers(*connection_);
|
registerSignalHandlers(*connection_);
|
||||||
|
@ -58,6 +58,9 @@ namespace sdbus::internal {
|
|||||||
void registerSignalHandler( const std::string& interfaceName
|
void registerSignalHandler( const std::string& interfaceName
|
||||||
, const std::string& signalName
|
, const std::string& signalName
|
||||||
, signal_handler signalHandler ) override;
|
, signal_handler signalHandler ) override;
|
||||||
|
void unregisterSignalHandler( const std::string& interfaceName
|
||||||
|
, const std::string& signalName ) override;
|
||||||
|
|
||||||
void finishRegistration() override;
|
void finishRegistration() override;
|
||||||
void unregister() override;
|
void unregister() override;
|
||||||
|
|
||||||
|
@ -114,3 +114,50 @@ TEST_F(SdbusTestObject, CanAccessAssociatedSignalMessageInSignalHandler)
|
|||||||
ASSERT_THAT(m_proxy->m_signalMsg, NotNull());
|
ASSERT_THAT(m_proxy->m_signalMsg, NotNull());
|
||||||
ASSERT_THAT(m_proxy->m_signalMemberName, Eq("simpleSignal"));
|
ASSERT_THAT(m_proxy->m_signalMemberName, Eq("simpleSignal"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_F(SdbusTestObject, UnregisterSignalHandler)
|
||||||
|
{
|
||||||
|
ASSERT_NO_THROW(m_proxy->unregisterSimpleSignalHandler());
|
||||||
|
|
||||||
|
m_adaptor->emitSimpleSignal();
|
||||||
|
|
||||||
|
ASSERT_FALSE(waitUntil(m_proxy->m_gotSimpleSignal));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(SdbusTestObject, UnregisterSignalHandlerForSomeProxies)
|
||||||
|
{
|
||||||
|
auto proxy1 = std::make_unique<TestProxy>(*s_adaptorConnection, BUS_NAME, OBJECT_PATH);
|
||||||
|
auto proxy2 = std::make_unique<TestProxy>(*s_adaptorConnection, BUS_NAME, OBJECT_PATH);
|
||||||
|
|
||||||
|
ASSERT_NO_THROW(m_proxy->unregisterSimpleSignalHandler());
|
||||||
|
|
||||||
|
m_adaptor->emitSimpleSignal();
|
||||||
|
|
||||||
|
ASSERT_TRUE(waitUntil(proxy1->m_gotSimpleSignal));
|
||||||
|
ASSERT_TRUE(waitUntil(proxy2->m_gotSimpleSignal));
|
||||||
|
ASSERT_FALSE(waitUntil(m_proxy->m_gotSimpleSignal));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(SdbusTestObject, FailsUnregisterSignalHandlerTwice)
|
||||||
|
{
|
||||||
|
ASSERT_NO_THROW(m_proxy->unregisterSimpleSignalHandler());
|
||||||
|
|
||||||
|
ASSERT_THROW(m_proxy->unregisterSimpleSignalHandler(), sdbus::Error);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(SdbusTestObject, ReRegisterSignalHandler)
|
||||||
|
{
|
||||||
|
// unregister simple-signal handler
|
||||||
|
ASSERT_NO_THROW(m_proxy->unregisterSimpleSignalHandler());
|
||||||
|
|
||||||
|
m_adaptor->emitSimpleSignal();
|
||||||
|
|
||||||
|
ASSERT_FALSE(waitUntil(m_proxy->m_gotSimpleSignal));
|
||||||
|
|
||||||
|
// re-register simple-signal handler
|
||||||
|
ASSERT_NO_THROW(m_proxy->reRegisterSimpleSignalHandler());
|
||||||
|
|
||||||
|
m_adaptor->emitSimpleSignal();
|
||||||
|
|
||||||
|
ASSERT_TRUE(waitUntil(m_proxy->m_gotSimpleSignal));
|
||||||
|
}
|
||||||
|
@ -169,6 +169,17 @@ public:
|
|||||||
proxy_.callMethod("emitTwoSimpleSignals").onInterface(INTERFACE_NAME);
|
proxy_.callMethod("emitTwoSimpleSignals").onInterface(INTERFACE_NAME);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void unregisterSimpleSignalHandler()
|
||||||
|
{
|
||||||
|
proxy_.muteSignal("simpleSignal").onInterface(INTERFACE_NAME);
|
||||||
|
}
|
||||||
|
|
||||||
|
void reRegisterSimpleSignalHandler()
|
||||||
|
{
|
||||||
|
proxy_.uponSignal("simpleSignal").onInterface(INTERFACE_NAME).call([this](){ this->onSimpleSignal(); });
|
||||||
|
proxy_.finishRegistration();
|
||||||
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
uint32_t action()
|
uint32_t action()
|
||||||
{
|
{
|
||||||
|
Reference in New Issue
Block a user