diff options
| author | Brad Bishop <bradleyb@fuzziesquirrel.com> | 2016-10-19 12:18:41 -0400 |
|---|---|---|
| committer | Brad Bishop <bradleyb@fuzziesquirrel.com> | 2016-11-08 14:45:39 -0500 |
| commit | 3d57f507b41860d11059904e87da61b4f25cfd82 (patch) | |
| tree | d20ad3953b1e6d9379003b1fc7085e2691969b1d | |
| parent | 49aefb3176d0a4c6d60ece4884d3850bcf9f75ca (diff) | |
| download | phosphor-inventory-manager-3d57f507b41860d11059904e87da61b4f25cfd82.tar.gz phosphor-inventory-manager-3d57f507b41860d11059904e87da61b4f25cfd82.zip | |
Enable filtering of signal matches
Provide tooling to enable specification of pre-implemented filtering
functors for signal matches.
Add a default 'none' filter to be used when a filter isn't specified.
Change-Id: I3549d8cf44c5f475626875fa94ca3ee8f74d6d26
Signed-off-by: Brad Bishop <bradleyb@fuzziesquirrel.com>
| -rw-r--r-- | README.md | 14 | ||||
| -rw-r--r-- | examples/match2.yaml | 2 | ||||
| -rw-r--r-- | filters.hpp | 122 | ||||
| -rw-r--r-- | manager.cpp | 5 | ||||
| -rw-r--r-- | manager.hpp | 3 | ||||
| -rwxr-xr-x | pimgen.py | 38 |
6 files changed, 180 insertions, 4 deletions
@@ -28,6 +28,20 @@ Subsequent tags are defined by the event type. Supported match tags are: * signature - A DBus match specification. +* filter - A filter to apply when a match occurs. + +---- +**filter** +Supported filter tags are: + +* name - The name of the filter. +* args - An optional list of arguments to pass to the filter. +* value - The argument value. +* type - The argument type (defaults to string if unspecified). + +The available filters provided by PIM are: + +* none - A non-filter. ---- diff --git a/examples/match2.yaml b/examples/match2.yaml index 3e11531..6fb9ff9 100644 --- a/examples/match2.yaml +++ b/examples/match2.yaml @@ -12,5 +12,7 @@ events: path: /xyz/openbmc_project/testing interface: org.freedesktop.DBus.Properties member: PropertiesChanged + filter: + name: none # vim: tabstop=8 expandtab shiftwidth=4 softtabstop=4 diff --git a/filters.hpp b/filters.hpp new file mode 100644 index 0000000..eb843a7 --- /dev/null +++ b/filters.hpp @@ -0,0 +1,122 @@ +#pragma once + +#include <utility> +#include <memory> +#include <sdbusplus/message.hpp> + +namespace phosphor +{ +namespace inventory +{ +namespace manager +{ +namespace filters +{ +namespace details +{ +namespace holder +{ + +/** @struct Base + * @brief Match event filter functor holder base. + * + * Provides an un-templated holder for filters of 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 bool operator()(sdbusplus::message::message &) const = 0; + virtual bool operator()(sdbusplus::message::message &msg) + { + return const_cast<const Base &>(*this)(msg); + } +}; + +/** @struct Holder + * @brief Match event filter functor holder. + * + * Adapts a functor of any type (with the correct function call + * signature) to a non-templated type usable by the manager for + * filtering. + * + * @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 bool operator()(sdbusplus::message::message &msg) const override + { + return _func(msg); + } + + virtual bool operator()(sdbusplus::message::message &msg) override + { + return _func(msg); + } + + private: + T _func; +}; + +} // namespace holder + +/** @struct Wrapper + * @brief Provides implicit type conversion from filter functors. + * + * Converts filter functors to ptr-to-holder. + */ +struct Wrapper +{ + template <typename T> + Wrapper(T &&func) : + _ptr(std::shared_ptr<holder::Base>( + new 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; + + bool operator()(sdbusplus::message::message &msg) + { + return (*_ptr)(msg); + } + bool operator()(sdbusplus::message::message &msg) const + { + return (*_ptr)(msg); + } + + private: + std::shared_ptr<holder::Base> _ptr; +}; + +} // namespace details + +/** @brief The default filter. */ +inline bool none(sdbusplus::message::message &) noexcept +{ + return true; +} + +} // namespace filters +} // namespace manager +} // namespace inventory +} // namespace phosphor + +// vim: tabstop=8 expandtab shiftwidth=4 softtabstop=4 diff --git a/manager.cpp b/manager.cpp index 36d47a6..8acd0ec 100644 --- a/manager.cpp +++ b/manager.cpp @@ -153,6 +153,11 @@ void Manager::notify(std::string path, Object object) void Manager::signal(sdbusplus::message::message &msg, auto &args) { // TODO - unstub + auto &filter = std::get<1>(args); + + if(filter(msg)) { + + } } #include "generated.hpp" diff --git a/manager.hpp b/manager.hpp index 9b8338b..0c78f74 100644 --- a/manager.hpp +++ b/manager.hpp @@ -6,6 +6,7 @@ #include <vector> #include <sdbusplus/server.hpp> #include <xyz/openbmc_project/Inventory/Manager/server.hpp> +#include "filters.hpp" namespace phosphor { @@ -121,7 +122,7 @@ class Manager final : /** @brief sd_bus signal callback. */ void signal(sdbusplus::message::message &, auto &); - using Event = std::tuple<const char *>; + using Event = std::tuple<const char *, filters::details::Wrapper>; using SigArgs = std::vector< std::unique_ptr< std::tuple< @@ -38,9 +38,10 @@ class ParseList(list): class MatchRender(object): - def __init__(self, name, signature): + def __init__(self, name, signature, fltr): self.name = valid_c_name_pattern.sub('_', name).lower() self.signature = signature + self.fltr = fltr if self.name in all_names: raise RuntimeError('The name "%s" is not unique.' % name) @@ -58,20 +59,51 @@ class MatchRender(object): fd.write(' std::make_tuple(\n') for s in sig: fd.write(' %s' % s) - fd.write('\n') + fd.write(',\n') + self.fltr(fd) fd.write(' ),\n') fd.write(' },\n') +class FilterRender(object): + namespace = 'filters' + default = 'none' + + def __init__(self, fltr): + self.args = None + if fltr is None: + self.name = self.default + else: + self.name = fltr.get('name') + self.args = fltr.get('args') + + def __call__(self, fd): + def fmt(x): + if x.get('type') is None: + return '"%s"' % x['value'] + return str(x['value']) + + fd.write(' %s::%s' % (self.namespace, self.name)) + if self.args: + fd.write('(') + buf = ','.join(([fmt(x) for x in self.args])) + fd.write(buf) + fd.write(')') + + fd.write('\n') + + class MatchEventParse(object): def __init__(self, match): self.name = match['name'] self.signature = match['signature'] + self.fltr = match.get('filter') def __call__(self): return MatchRender( self.name, - self.signature) + self.signature, + FilterRender(self.fltr)) class EventsParse(object): |

