Add actions
Provide tooling to enable specification of pre-implemented actions
to perform after a signal match.
Add a default 'noop' action to be used when an action isn't specified.
Change-Id: I8d3b1ef2cfc26771322820be931a61bba3ad8d94
Signed-off-by: Brad Bishop <bradleyb@fuzziesquirrel.com>
diff --git a/README.md b/README.md
index e2415c0..5e9b597 100644
--- a/README.md
+++ b/README.md
@@ -20,10 +20,24 @@
* name - A globally unique event name.
* type - The event type. Supported types are: *match*.
+* action - The response to the event.
Subsequent tags are defined by the event type.
----
+**action**
+Supported action tags are:
+
+* name - The action name.
+* args - An optional list of arguments to pass to the action.
+* value - The argument value.
+* type - The argument type (defaults to string if unspecified).
+
+The available actions provided by PIM are:
+
+* noop - A non-action.
+
+----
**match**
Supported match tags are:
diff --git a/actions.hpp b/actions.hpp
new file mode 100644
index 0000000..57a2f6f
--- /dev/null
+++ b/actions.hpp
@@ -0,0 +1,119 @@
+#pragma once
+
+#include <utility>
+#include <memory>
+
+namespace phosphor
+{
+namespace inventory
+{
+namespace manager
+{
+namespace actions
+{
+namespace details
+{
+namespace holder
+{
+
+/** @struct Base
+ * @brief Event action functor holder base.
+ *
+ * Provides an un-templated holder for actionsof any type with the correct
+ * function call signature.
+ */
+struct Base
+{
+ Base() = default;
+ virtual ~Base() = default;
+ Base(const Base&) = delete;
+ Base& operator=(const Base&) = delete;
+ Base(Base&&) = default;
+ Base& operator=(Base&&) = default;
+
+ virtual void operator()() const = 0;
+ virtual void operator()()
+ {
+ const_cast<const Base &>(*this)();
+ }
+};
+
+/** @struct Holder
+ * @brief Event action functor holder.
+ *
+ * Adapts a functor of any type (with the correct function call
+ * signature) to a non-templated type usable by the manager for
+ * actions.
+ *
+ * @tparam T - The functor type.
+ */
+template <typename T>
+struct Holder final : public Base
+{
+ Holder() = delete;
+ ~Holder() = default;
+ Holder(const Holder&) = delete;
+ Holder & operator=(const Holder&) = delete;
+ Holder(Holder&&) = default;
+ Holder& operator=(Holder&&) = default;
+ explicit Holder(T &&func) : _func(std::forward<T>(func)) {}
+
+ virtual void operator()() const override
+ {
+ _func();
+ }
+
+ virtual void operator()() override
+ {
+ _func();
+ }
+
+ private:
+ T _func;
+};
+
+} // namespace holder
+
+/** @struct Wrapper
+ * @brief Provides implicit type conversion from action functors.
+ *
+ * Converts action functors to ptr-to-holder.
+ */
+struct Wrapper
+{
+ template <typename T>
+ Wrapper(T &&func) :
+ _ptr(static_cast<std::shared_ptr<holder::Base>>(
+ std::make_shared<holder::Holder<T>>(
+ std::forward<T>(func)))) { }
+
+ ~Wrapper() = default;
+ Wrapper(const Wrapper&) = default;
+ Wrapper& operator=(const Wrapper&) = delete;
+ Wrapper(Wrapper&&) = default;
+ Wrapper& operator=(Wrapper&&) = default;
+
+ void operator()()
+ {
+ (*_ptr)();
+ }
+ void operator()() const
+ {
+ (*_ptr)();
+ }
+
+ private:
+ std::shared_ptr<holder::Base> _ptr;
+};
+
+} // namespace details
+
+/** @brief The default action. */
+inline void noop() noexcept { }
+
+} // namespace actions
+} // namespace manager
+} // namespace inventory
+} // namespace phosphor
+
+// vim: tabstop=8 expandtab shiftwidth=4 softtabstop=4
diff --git a/examples/match1.yaml b/examples/match1.yaml
index 9388a90..87e5148 100644
--- a/examples/match1.yaml
+++ b/examples/match1.yaml
@@ -10,5 +10,7 @@
type: signal
interface: org.freedesktop.DBus.Properties
member: PropertiesChanged
+ action:
+ name: noop
# vim: tabstop=8 expandtab shiftwidth=4 softtabstop=4
diff --git a/manager.cpp b/manager.cpp
index 8acd0ec..8e185ac 100644
--- a/manager.cpp
+++ b/manager.cpp
@@ -152,11 +152,11 @@
void Manager::signal(sdbusplus::message::message &msg, auto &args)
{
- // TODO - unstub
auto &filter = std::get<1>(args);
+ auto &action = std::get<2>(args);
if(filter(msg)) {
-
+ action();
}
}
diff --git a/manager.hpp b/manager.hpp
index 0c78f74..23d91da 100644
--- a/manager.hpp
+++ b/manager.hpp
@@ -7,6 +7,7 @@
#include <sdbusplus/server.hpp>
#include <xyz/openbmc_project/Inventory/Manager/server.hpp>
#include "filters.hpp"
+#include "actions.hpp"
namespace phosphor
{
@@ -122,7 +123,10 @@
/** @brief sd_bus signal callback. */
void signal(sdbusplus::message::message &, auto &);
- using Event = std::tuple<const char *, filters::details::Wrapper>;
+ using Event = std::tuple<
+ const char *,
+ filters::details::Wrapper,
+ actions::details::Wrapper>;
using SigArgs = std::vector<
std::unique_ptr<
std::tuple<
diff --git a/pimgen.py b/pimgen.py
index 8350d3a..37819d3 100755
--- a/pimgen.py
+++ b/pimgen.py
@@ -38,10 +38,11 @@
class MatchRender(object):
- def __init__(self, name, signature, fltr):
+ def __init__(self, name, signature, fltr, action):
self.name = valid_c_name_pattern.sub('_', name).lower()
self.signature = signature
self.fltr = fltr
+ self.action = action
if self.name in all_names:
raise RuntimeError('The name "%s" is not unique.' % name)
@@ -61,6 +62,9 @@
fd.write(' %s' % s)
fd.write(',\n')
self.fltr(fd)
+ fd.write(',\n')
+ self.action(fd)
+ fd.write('\n')
fd.write(' ),\n')
fd.write(' },\n')
@@ -90,7 +94,13 @@
fd.write(buf)
fd.write(')')
- fd.write('\n')
+
+class ActionRender(FilterRender):
+ namespace = 'actions'
+ default = 'noop'
+
+ def __init__(self, action):
+ FilterRender.__init__(self, action)
class MatchEventParse(object):
@@ -98,12 +108,14 @@
self.name = match['name']
self.signature = match['signature']
self.fltr = match.get('filter')
+ self.action = match.get('action')
def __call__(self):
return MatchRender(
self.name,
self.signature,
- FilterRender(self.fltr))
+ FilterRender(self.fltr),
+ ActionRender(self.action))
class EventsParse(object):