summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/functor.hpp63
-rw-r--r--src/monitor.cpp32
-rw-r--r--src/monitor.hpp14
3 files changed, 109 insertions, 0 deletions
diff --git a/src/functor.hpp b/src/functor.hpp
index c2c586e..b3ad9a0 100644
--- a/src/functor.hpp
+++ b/src/functor.hpp
@@ -23,6 +23,59 @@ auto make_action(T&& action)
return Action(std::forward<T>(action));
}
+template <typename T, typename U>
+struct PropertyChangedCondition
+{
+ PropertyChangedCondition() = delete;
+ ~PropertyChangedCondition() = default;
+ PropertyChangedCondition(const PropertyChangedCondition&) = default;
+ PropertyChangedCondition& operator=(const PropertyChangedCondition&) =
+ default;
+ PropertyChangedCondition(PropertyChangedCondition&&) = default;
+ PropertyChangedCondition& operator=(PropertyChangedCondition&&) =
+ default;
+ PropertyChangedCondition(const char* iface, const char* property,
+ U&& condition) :
+ _iface(iface),
+ _property(property),
+ _condition(std::forward<U>(condition)) { }
+
+ /** @brief Test a property value.
+ *
+ * Extract the property from the PropertiesChanged
+ * message and run the condition test.
+ */
+ bool operator()(
+ sdbusplus::bus::bus&,
+ sdbusplus::message::message& msg,
+ Monitor&) const
+ {
+ std::map<std::string, sdbusplus::message::variant<T>> properties;
+ const char* iface = nullptr;
+
+ msg.read(iface);
+ if (!iface || strcmp(iface, _iface))
+ {
+ return false;
+ }
+
+ msg.read(properties);
+ auto it = properties.find(_property);
+ if (it == properties.cend())
+ {
+ return false;
+ }
+
+ return _condition(
+ std::forward<T>(it->second.template get<T>()));
+ }
+
+private:
+ const char* _iface;
+ const char* _property;
+ U _condition;
+};
+
struct PropertyConditionBase
{
PropertyConditionBase() = delete;
@@ -125,6 +178,16 @@ private:
};
template <typename T, typename U>
+auto propertySignal(const char* iface,
+ const char* property,
+ U&& condition)
+{
+ return PropertyChangedCondition<T, U>(iface,
+ property,
+ std::move(condition));
+}
+
+template <typename T, typename U>
auto propertyStart(const char* path,
const char* iface,
const char* property,
diff --git a/src/monitor.cpp b/src/monitor.cpp
index 2864924..aeb1fe5 100644
--- a/src/monitor.cpp
+++ b/src/monitor.cpp
@@ -16,7 +16,26 @@ const std::vector<std::tuple<std::vector<std::shared_ptr<Event>>,
Monitor::Monitor(sdbusplus::bus::bus& bus) :
bus(bus)
{
+ // Process thru given events that are type 'signal'
+ for (auto& event : events)
+ {
+ for (auto& pEvent : std::get<std::vector<std::shared_ptr<Event>>>(event))
+ {
+ if (pEvent->trigger != Event::Trigger::SIGNAL)
+ {
+ continue;
+ }
+ auto signalEvent = static_cast<SignalEvent*>(pEvent.get());
+ eventArgs.emplace_back(std::make_unique<eventArg>(this,
+ signalEvent,
+ &event));
+ matches.emplace_back(bus,
+ signalEvent->signature,
+ handleSignal,
+ eventArgs.back().get());
+ }
+ }
}
void Monitor::processStart() noexcept
@@ -36,6 +55,19 @@ void Monitor::processStart() noexcept
}
}
+int Monitor::handleSignal(sd_bus_message* msg,
+ void* data,
+ sd_bus_error* err)
+{
+ auto sdbpMsg = sdbusplus::message::message(msg);
+ auto& eventArg = *static_cast<Monitor::eventArg*>(data);
+ std::get<0>(eventArg)->handleEvent(
+ sdbpMsg,
+ static_cast<const SignalEvent&>(*std::get<1>(eventArg)),
+ *std::get<2>(eventArg));
+ return 0;
+}
+
void Monitor::handleEvent(sdbusplus::message::message& msg,
const Event& event,
const std::tuple<std::vector<std::shared_ptr<Event>>,
diff --git a/src/monitor.hpp b/src/monitor.hpp
index aca64d8..5256582 100644
--- a/src/monitor.hpp
+++ b/src/monitor.hpp
@@ -30,6 +30,12 @@ class Monitor
const std::tuple<std::vector<std::shared_ptr<Event>>,
std::vector<Action>>& eventDef);
+ using eventArg = std::tuple<Monitor*,
+ const SignalEvent*,
+ const std::tuple<
+ std::vector<std::shared_ptr<Event>>,
+ std::vector<Action>>*>;
+
private:
sdbusplus::bus::bus& bus;
@@ -37,6 +43,14 @@ class Monitor
std::tuple<std::vector<std::shared_ptr<Event>>,
std::vector<Action>>> events;
+ std::vector<std::unique_ptr<eventArg>> eventArgs;
+
+ std::vector<sdbusplus::server::match::match> matches;
+
+ static int handleSignal(sd_bus_message* msg,
+ void* data,
+ sd_bus_error* err);
+
};
} // namespace monitoring
OpenPOWER on IntegriCloud