From 336f18a541e93e2cc1719180df73ef8b357c962f Mon Sep 17 00:00:00 2001 From: Matthew Barth Date: Tue, 26 Sep 2017 09:15:56 -0500 Subject: Update event initialization Using a null dbus message to the event signal will perform the necessary steps to initialize the event parameters using the given signal handler's function directly. i.e.) In the case for subscribing to PropertiesChanged signals, initially the given property must be read. When the PropertiesChanged signal struct is given a null message, it finds the property, reads the value, and then can perform the given signal handler function directly. This produces the same functional path as receiving a PropertiesChanged signal containing the property value within the message. Change-Id: I35575cfff66eb0305156be786cb1f5536d42bb1c Signed-off-by: Matthew Barth --- control/functor.hpp | 136 +++++++++++++++++++++++++++++++++------------------- 1 file changed, 88 insertions(+), 48 deletions(-) (limited to 'control/functor.hpp') diff --git a/control/functor.hpp b/control/functor.hpp index a5044da..daaa1b7 100644 --- a/control/functor.hpp +++ b/control/functor.hpp @@ -1,6 +1,7 @@ #pragma once #include "types.hpp" +#include "sdbusplus.hpp" #include namespace phosphor @@ -11,7 +12,10 @@ namespace control { class Zone; +using namespace phosphor::fan; using namespace phosphor::logging; +using InternalFailure = sdbusplus::xyz::openbmc_project::Common:: + Error::InternalFailure; /** * @brief Create a handler function object @@ -55,9 +59,11 @@ struct PropertyChanged PropertyChanged& operator=(const PropertyChanged&) = default; PropertyChanged(PropertyChanged&&) = default; PropertyChanged& operator=(PropertyChanged&&) = default; - PropertyChanged(const char* iface, + PropertyChanged(const char* path, + const char* iface, const char* property, U&& handler) : + _path(path), _iface(iface), _property(property), _handler(std::forward(handler)) { } @@ -65,35 +71,61 @@ struct PropertyChanged /** @brief Run signal handler function * * Extract the property from the PropertiesChanged - * message and run the handler function. + * message (or read the property when the message is null) + * and run the handler function. */ - void operator()(sdbusplus::bus::bus&, + void operator()(sdbusplus::bus::bus& bus, sdbusplus::message::message& msg, Zone& zone) const { - std::map> properties; - const char* iface = nullptr; - - msg.read(iface); - if (!iface || strcmp(iface, _iface)) + if (msg) { - return; - } + std::map> properties; + const char* iface = nullptr; - msg.read(properties); - auto it = properties.find(_property); - if (it == properties.cend()) + msg.read(iface); + if (!iface || strcmp(iface, _iface)) + { + return; + } + + msg.read(properties); + auto it = properties.find(_property); + if (it == properties.cend()) + { + log("Unable to find property on interface", + entry("PROPERTY=%s", _property), + entry("INTERFACE=%s", _iface)); + return; + } + + _handler(zone, std::forward(it->second.template get())); + } + else { - log("Unable to find property on interface", - entry("PROPERTY=%s", _property), - entry("INTERFACE=%s", _iface)); - return; + try + { + auto val = util::SDBusPlus::getProperty(bus, + _path, + _iface, + _property); + _handler(zone, std::forward(val)); + } + catch (const InternalFailure& ife) + { + // Property will not be used unless a property changed + // signal message is received for this property. + log( + "Property not used, unless PropertyChanged signal received", + entry("PATH=%s", _path), + entry("INTERFACE=%s", _iface), + entry("PROPERTY=%s", _property)); + } } - - _handler(zone, std::forward(it->second.template get())); } private: + const char* _path; const char* _iface; const char* _property; U _handler; @@ -102,19 +134,24 @@ private: /** * @brief Used to process a Dbus property changed signal event * - * @param[in] iface - Sensor value interface - * @param[in] property - Sensor value property + * @param[in] path - Object path + * @param[in] iface - Object interface + * @param[in] property - Object property * @param[in] handler - Handler function to perform * * @tparam T - The type of the property * @tparam U - The type of the handler */ template -auto propertySignal(const char* iface, +auto propertySignal(const char* path, + const char* iface, const char* property, U&& handler) { - return PropertyChanged(iface, property, std::forward(handler)); + return PropertyChanged(path, + iface, + property, + std::forward(handler)); } /** @@ -151,34 +188,37 @@ struct InterfaceAdded sdbusplus::message::message& msg, Zone& zone) const { - std::map>> intfProp; - sdbusplus::message::object_path op; - - msg.read(op); - auto objPath = static_cast(op).c_str(); - if (!objPath || strcmp(objPath, _path)) + if (msg) { - // Object path does not match this handler's path - return; - } + std::map>> intfProp; + sdbusplus::message::object_path op; - msg.read(intfProp); - auto itIntf = intfProp.find(_iface); - if (itIntf == intfProp.cend()) - { - // Interface not found on this handler's path - return; - } - auto itProp = itIntf->second.find(_property); - if (itProp == itIntf->second.cend()) - { - // Property not found on this handler's path - return; - } + msg.read(op); + auto objPath = static_cast(op).c_str(); + if (!objPath || strcmp(objPath, _path)) + { + // Object path does not match this handler's path + return; + } - _handler(zone, std::forward(itProp->second.template get())); + msg.read(intfProp); + auto itIntf = intfProp.find(_iface); + if (itIntf == intfProp.cend()) + { + // Interface not found on this handler's path + return; + } + auto itProp = itIntf->second.find(_property); + if (itProp == itIntf->second.cend()) + { + // Property not found on this handler's path + return; + } + + _handler(zone, std::forward(itProp->second.template get())); + } } private: -- cgit v1.2.1