control: Correct same signal object subscription of actions
When the same signal for a signal object is subscribed to (such as
across events), the actions should be included on the list of actions to
be called when that specific signal is received. Previously these
actions were being moved off the event's list of actions, which was not
ideal. This instead copies a reference to the event's list of actions to
the list of actions to be called when the particular signal is received.
Change-Id: I260f7134a67ec82f9e90a66c4cfe9189ca7d4304
Signed-off-by: Matthew Barth <msbarth@us.ibm.com>
diff --git a/control/json/manager.cpp b/control/json/manager.cpp
index 8973d7c..978fde4 100644
--- a/control/json/manager.cpp
+++ b/control/json/manager.cpp
@@ -668,8 +668,12 @@
{
// Perform the actions in the handler package
auto& actions = std::get<SignalActions>(pkg);
- std::for_each(actions.begin(), actions.end(),
- [](auto& action) { action.get()->run(); });
+ std::for_each(actions.begin(), actions.end(), [](auto& action) {
+ if (action.get())
+ {
+ action.get()->run();
+ }
+ });
}
// Only rewind message when not last package
if (&pkg != &pkgs->back())
diff --git a/control/json/manager.hpp b/control/json/manager.hpp
index 310132d..c783e44 100644
--- a/control/json/manager.hpp
+++ b/control/json/manager.hpp
@@ -86,7 +86,8 @@
constexpr auto Prop = 2;
using SignalObject = std::tuple<std::string, std::string, std::string>;
/* Dbus signal actions */
-using SignalActions = std::vector<std::unique_ptr<ActionBase>>&;
+using SignalActions =
+ std::vector<std::reference_wrapper<std::unique_ptr<ActionBase>>>;
/**
* Signal handler function that handles parsing a signal's message for a
* particular signal object and stores the results in the manager
diff --git a/control/json/triggers/signal.cpp b/control/json/triggers/signal.cpp
index f430bfe..70bc8be 100644
--- a/control/json/triggers/signal.cpp
+++ b/control/json/triggers/signal.cpp
@@ -74,13 +74,12 @@
{
if (isSameSig(pkg))
{
- // Same signal expected, add actions to be run when signal
- // received
+ // Same SignalObject signal to trigger event actions,
+ // add actions to be run when signal for SignalObject received
auto& pkgActions = std::get<SignalActions>(signalPkg);
auto& actions = std::get<SignalActions>(pkg);
- actions.insert(actions.end(),
- std::make_move_iterator(pkgActions.begin()),
- std::make_move_iterator(pkgActions.end()));
+ actions.insert(actions.end(), pkgActions.begin(),
+ pkgActions.end());
sameSignal = true;
break;
}
@@ -93,7 +92,7 @@
}
}
-void propertiesChanged(Manager* mgr, const Group& group, SignalActions actions,
+void propertiesChanged(Manager* mgr, const Group& group, SignalActions& actions,
const json&)
{
// Groups are optional, but a signal triggered event with no groups
@@ -108,7 +107,7 @@
SignalObject(std::cref(member),
std::cref(group.getInterface()),
std::cref(group.getProperty())),
- SignalActions(actions)};
+ actions};
auto isSameSig = [&prop = group.getProperty()](SignalPkg& pkg) {
auto& obj = std::get<SignalObject>(pkg);
return prop == std::get<Prop>(obj);
@@ -118,7 +117,7 @@
}
}
-void interfacesAdded(Manager* mgr, const Group& group, SignalActions actions,
+void interfacesAdded(Manager* mgr, const Group& group, SignalActions& actions,
const json&)
{
// Groups are optional, but a signal triggered event with no groups
@@ -132,7 +131,7 @@
SignalObject(std::cref(member),
std::cref(group.getInterface()),
std::cref(group.getProperty())),
- SignalActions(actions)};
+ actions};
auto isSameSig = [&intf = group.getInterface()](SignalPkg& pkg) {
auto& obj = std::get<SignalObject>(pkg);
return intf == std::get<Intf>(obj);
@@ -142,7 +141,7 @@
}
}
-void interfacesRemoved(Manager* mgr, const Group& group, SignalActions actions,
+void interfacesRemoved(Manager* mgr, const Group& group, SignalActions& actions,
const json&)
{
// Groups are optional, but a signal triggered event with no groups
@@ -155,7 +154,7 @@
SignalObject(std::cref(member),
std::cref(group.getInterface()),
std::cref(group.getProperty())),
- SignalActions(actions)};
+ actions};
auto isSameSig = [&intf = group.getInterface()](SignalPkg& pkg) {
auto& obj = std::get<SignalObject>(pkg);
return intf == std::get<Intf>(obj);
@@ -165,7 +164,7 @@
}
}
-void nameOwnerChanged(Manager* mgr, const Group& group, SignalActions actions,
+void nameOwnerChanged(Manager* mgr, const Group& group, SignalActions& actions,
const json&)
{
std::vector<std::string> grpServices;
@@ -190,7 +189,7 @@
SignalObject(std::cref(member),
std::cref(group.getInterface()),
std::cref(group.getProperty())),
- SignalActions(actions)};
+ actions};
// If signal match already exists, then the service will be the
// same so add action to be run
auto isSameSig = [](SignalPkg& pkg) { return true; };
@@ -214,12 +213,11 @@
}
}
-void member(Manager* mgr, const Group& group, SignalActions actions,
+void member(Manager* mgr, const Group& group, SignalActions& actions,
const json&)
{
// No SignalObject required to associate to this signal
- SignalPkg signalPkg = {Handlers::member, SignalObject(),
- SignalActions(actions)};
+ SignalPkg signalPkg = {Handlers::member, SignalObject(), actions};
// If signal match already exists, then the member signal will be the
// same so add action to be run
auto isSameSig = [](SignalPkg& pkg) { return true; };
@@ -238,7 +236,7 @@
}
enableTrigger triggerSignal(const json& jsonObj, const std::string& eventName,
- SignalActions actions)
+ std::vector<std::unique_ptr<ActionBase>>& actions)
{
auto subscriber = signals.end();
if (jsonObj.contains("signal"))
@@ -267,10 +265,15 @@
jsonObj](const std::string& eventName, Manager* mgr,
const std::vector<Group>& groups,
std::vector<std::unique_ptr<ActionBase>>& actions) {
+ SignalActions signalActions;
+ std::for_each(actions.begin(), actions.end(),
+ [&signalActions](auto& action) {
+ signalActions.emplace_back(std::ref(action));
+ });
for (const auto& group : groups)
{
// Call signal subscriber for each group
- subscriber->second(mgr, group, actions, jsonObj);
+ subscriber->second(mgr, group, signalActions, jsonObj);
}
};
}
diff --git a/control/json/triggers/signal.hpp b/control/json/triggers/signal.hpp
index 6db4dbb..675bd21 100644
--- a/control/json/triggers/signal.hpp
+++ b/control/json/triggers/signal.hpp
@@ -50,7 +50,7 @@
* @param[in] group - Group to subscribe signal against
* @param[in] actions - Actions to be run when signal is received
*/
-void propertiesChanged(Manager* mgr, const Group& group, SignalActions actions,
+void propertiesChanged(Manager* mgr, const Group& group, SignalActions& actions,
const json&);
/**
@@ -60,7 +60,7 @@
* @param[in] group - Group to subscribe signal against
* @param[in] actions - Actions to be run when signal is received
*/
-void interfacesAdded(Manager* mgr, const Group& group, SignalActions actions,
+void interfacesAdded(Manager* mgr, const Group& group, SignalActions& actions,
const json&);
/**
@@ -70,7 +70,7 @@
* @param[in] group - Group to subscribe signal against
* @param[in] actions - Actions to be run when signal is received
*/
-void interfacesRemoved(Manager* mgr, const Group& group, SignalActions actions,
+void interfacesRemoved(Manager* mgr, const Group& group, SignalActions& actions,
const json&);
/**
@@ -80,7 +80,7 @@
* @param[in] group - Group to subscribe signal against
* @param[in] actions - Actions to be run when signal is received
*/
-void nameOwnerChanged(Manager* mgr, const Group& group, SignalActions actions,
+void nameOwnerChanged(Manager* mgr, const Group& group, SignalActions& actions,
const json&);
/**
@@ -90,12 +90,12 @@
* @param[in] group - Group to subscribe signal against
* @param[in] actions - Actions to be run when signal is received
*/
-void member(Manager* mgr, const Group& group, SignalActions actions,
+void member(Manager* mgr, const Group& group, SignalActions& actions,
const json&);
// Match setup function for signals
-using SignalMatch = std::function<void(Manager*, const Group&,
- SignalActions actions, const json&)>;
+using SignalMatch =
+ std::function<void(Manager*, const Group&, SignalActions&, const json&)>;
/* Supported signals to their corresponding match setup functions */
static const std::unordered_map<std::string, SignalMatch> signals = {
@@ -117,6 +117,6 @@
* configuration, is received.
*/
enableTrigger triggerSignal(const json& jsonObj, const std::string& eventName,
- SignalActions actions);
+ std::vector<std::unique_ptr<ActionBase>>& actions);
} // namespace phosphor::fan::control::json::trigger::signal