summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/Makefile.am1
-rw-r--r--src/callback.hpp38
-rw-r--r--src/example/example.yaml19
-rwxr-xr-xsrc/pdmgen.py62
-rw-r--r--src/templates/callbackgroup.mako.cpp2
-rw-r--r--src/templates/generated.mako.hpp17
6 files changed, 139 insertions, 0 deletions
diff --git a/src/Makefile.am b/src/Makefile.am
index f223713..c77c0a8 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -22,6 +22,7 @@ BUILT_SOURCES = generated.hpp
CLEANFILES = generated.hpp
TEMPLATES = \
+ templates/callbackgroup.mako.cpp \
templates/generated.mako.hpp \
templates/journal.mako.cpp
diff --git a/src/callback.hpp b/src/callback.hpp
index d7a678c..7c6f69b 100644
--- a/src/callback.hpp
+++ b/src/callback.hpp
@@ -52,6 +52,44 @@ class IndexedCallback : public Callback
const PropertyIndex& index;
};
+/** @class GroupOfCallbacks
+ * @brief Invoke multiple callbacks.
+ *
+ * A group of callbacks is implemented as a vector of array indicies
+ * into an external array of callbacks. The group function call
+ * operator traverses the vector of indicies, invoking each
+ * callback.
+ *
+ * @tparam CallbackAccess - Access to the array of callbacks.
+ */
+template <typename CallbackAccess>
+class GroupOfCallbacks : public Callback
+{
+ public:
+ GroupOfCallbacks() = delete;
+ GroupOfCallbacks(const GroupOfCallbacks&) = delete;
+ GroupOfCallbacks(GroupOfCallbacks&&) = default;
+ GroupOfCallbacks& operator=(const GroupOfCallbacks&) = delete;
+ GroupOfCallbacks& operator=(GroupOfCallbacks&&) = default;
+ ~GroupOfCallbacks() = default;
+ explicit GroupOfCallbacks(
+ const std::vector<size_t>& graphEntry)
+ : graph(graphEntry) {}
+
+ /** @brief Run the callbacks. */
+ void operator()() override
+ {
+ for (auto e : graph)
+ {
+ (*CallbackAccess::get()[e])();
+ }
+ }
+
+ private:
+ /** @brief The offsets of the callbacks in the group. */
+ const std::vector<size_t>& graph;
+};
+
} // namespace monitoring
} // namespace dbus
} // namespace phosphor
diff --git a/src/example/example.yaml b/src/example/example.yaml
index 171aeaa..0f286dc 100644
--- a/src/example/example.yaml
+++ b/src/example/example.yaml
@@ -74,3 +74,22 @@
properties: example property group
severity: INFO
message: Hello world from PDM!
+
+- name: example callback group
+ description: >
+ 'Callbacks groups are simply named collections of other callbacks.
+ Configuration file directives can only refer to a single callback.
+ Through use of a group, these configuration file directives can
+ refer to more than one callback.
+
+ For example for a given event, one may wish to trace multiple
+ messages to the systemd journal. The journal callback does not
+ support tracing multiple messages. To do that, define a callback
+ group composed of multiple journal callbacks.
+
+ This example callback group only has one member. To add more, add
+ additional callbacks to the members element.'
+ class: callback
+ callback: group
+ members:
+ - example journal callback
diff --git a/src/pdmgen.py b/src/pdmgen.py
index e4a97e7..b20436e 100755
--- a/src/pdmgen.py
+++ b/src/pdmgen.py
@@ -436,6 +436,65 @@ class Journal(Callback, Renderer):
indent=indent)
+class CallbackGraphEntry(Group):
+ '''An entry in a traversal list for groups of callbacks.'''
+
+ def __init__(self, *a, **kw):
+ super(CallbackGraphEntry, self).__init__(**kw)
+
+ def setup(self, objs):
+ '''Resolve group members.'''
+
+ def map_member(x):
+ return get_index(
+ objs, 'callback', x, config=self.configfile)
+
+ self.members = map(
+ map_member,
+ self.members)
+
+ super(CallbackGraphEntry, self).setup(objs)
+
+
+class GroupOfCallbacks(ConfigEntry, Renderer):
+ '''Handle the callback group config file directive.'''
+
+ def __init__(self, *a, **kw):
+ self.members = kw.pop('members')
+ super(GroupOfCallbacks, self).__init__(**kw)
+
+ def factory(self, objs):
+ '''Create a graph instance for this group of callbacks.'''
+
+ args = {
+ 'configfile': self.configfile,
+ 'members': self.members,
+ 'class': 'callbackgroup',
+ 'callbackgroup': 'callback',
+ 'name': self.members
+ }
+
+ entry = CallbackGraphEntry(**args)
+ add_unique(entry, objs, config=self.configfile)
+
+ super(GroupOfCallbacks, self).factory(objs)
+
+ def setup(self, objs):
+ '''Resolve graph entry.'''
+
+ self.graph = get_index(
+ objs, 'callbackgroup', self.members, config=self.configfile)
+
+ super(GroupOfCallbacks, self).setup(objs)
+
+ def construct(self, loader, indent):
+ return self.render(
+ loader,
+ 'callbackgroup.mako.cpp',
+ c=self,
+ indent=indent)
+
+
class Everything(Renderer):
'''Parse/render entry point.'''
@@ -465,6 +524,7 @@ class Everything(Renderer):
},
'callback': {
'journal': Journal,
+ 'group': GroupOfCallbacks,
},
}
@@ -556,6 +616,7 @@ class Everything(Renderer):
self.instancegroups = kw.pop('instancegroup', [])
self.watches = kw.pop('watch', [])
self.callbacks = kw.pop('callback', [])
+ self.callbackgroups = kw.pop('callbackgroup', [])
super(Everything, self).__init__(**kw)
@@ -578,6 +639,7 @@ class Everything(Renderer):
watches=self.watches,
instancegroups=self.instancegroups,
callbacks=self.callbacks,
+ callbackgroups=self.callbackgroups,
indent=Indent()))
if __name__ == '__main__':
diff --git a/src/templates/callbackgroup.mako.cpp b/src/templates/callbackgroup.mako.cpp
new file mode 100644
index 0000000..6cc6813
--- /dev/null
+++ b/src/templates/callbackgroup.mako.cpp
@@ -0,0 +1,2 @@
+std::make_unique<GroupOfCallbacks<ConfigPropertyCallbacks>>(
+${indent(1)}ConfigPropertyCallbackGroups::get()[${c.graph}])\
diff --git a/src/templates/generated.mako.hpp b/src/templates/generated.mako.hpp
index 61c2b6f..67b9149 100644
--- a/src/templates/generated.mako.hpp
+++ b/src/templates/generated.mako.hpp
@@ -128,6 +128,23 @@ struct ConfigPropertyIndicies
}
};
+struct ConfigPropertyCallbackGroups
+{
+ using CallbackGroups = std::array<std::vector<size_t>, ${len(callbackgroups)}>;
+ static auto& get()
+ {
+ static const CallbackGroups propertyCallbackGraph =
+ {
+ {
+% for g in callbackgroups:
+ {${', '.join([str(x) for x in g.members])}},
+% endfor
+ }
+ };
+ return propertyCallbackGraph;
+ }
+};
+
struct ConfigPropertyCallbacks
{
using Callbacks = std::array<std::unique_ptr<Callback>, ${len(callbacks)}>;
OpenPOWER on IntegriCloud