diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/callback.hpp | 78 | ||||
-rw-r--r-- | src/example/example.yaml | 27 | ||||
-rwxr-xr-x | src/pdmgen.py | 3 | ||||
-rw-r--r-- | src/templates/conditional.mako.cpp | 7 | ||||
-rw-r--r-- | src/templates/generated.mako.hpp | 2 |
5 files changed, 111 insertions, 6 deletions
diff --git a/src/callback.hpp b/src/callback.hpp index f7886cb..06df910 100644 --- a/src/callback.hpp +++ b/src/callback.hpp @@ -1,5 +1,6 @@ #pragma once +#include <chrono> #include "data_types.hpp" namespace phosphor @@ -146,14 +147,14 @@ class ConditionalCallback: public Callback ConditionalCallback(ConditionalCallback&&) = default; ConditionalCallback& operator=(const ConditionalCallback&) = delete; ConditionalCallback& operator=(ConditionalCallback&&) = default; - ~ConditionalCallback() = default; + virtual ~ConditionalCallback() = default; ConditionalCallback( const std::vector<size_t>& graphEntry, Conditional& cond) : graph(graphEntry), condition(cond) {} /** @brief Run the callback if the condition is satisfied. */ - void operator()() override + virtual void operator()() override { if (condition()) { @@ -161,7 +162,7 @@ class ConditionalCallback: public Callback } } - private: + protected: /** @brief The index of the callback to conditionally invoke. */ const std::vector<size_t>& graph; @@ -169,6 +170,77 @@ class ConditionalCallback: public Callback Conditional& condition; }; +/** @class DeferrableCallback + * + * Deferrable callbacks wait a configurable period before + * invoking their associated callback. + * + * When the callback condition is initally met, start a timer. If the + * condition is tested again before the timer expires and it is not + * met cancel the timer. If the timer expires invoke the associated + * callback. + * + * @tparam CallbackAccess - Provide access to callback group instances. + * @tparam TimerType - Delegated timer access methods. + */ +template <typename CallbackAccess, typename TimerType> +class DeferrableCallback : public ConditionalCallback<CallbackAccess> +{ + public: + DeferrableCallback() = delete; + DeferrableCallback(const DeferrableCallback&) = delete; + DeferrableCallback(DeferrableCallback&&) = default; + DeferrableCallback& operator=(const DeferrableCallback&) = delete; + DeferrableCallback& operator=(DeferrableCallback&&) = default; + ~DeferrableCallback() = default; + + DeferrableCallback( + const std::vector<size_t>& graphEntry, + Conditional& cond, + const std::chrono::microseconds& delay) + : ConditionalCallback<CallbackAccess>(graphEntry, cond), + delayInterval(delay), + timer(nullptr) {} + + void operator()() override + { + if (!timer) + { + timer = std::make_unique<TimerType>( +// **INDENT-OFF** + [this](auto & source) + { + this->ConditionalCallback<CallbackAccess>::operator()(); + }); +// **INDENT-ON** + timer->disable(); + } + + if (this->condition()) + { + if (!timer->enabled()) + { + // This is the first time the condition evaluated. + // Start the countdown. + timer->update(timer->now() + delayInterval); + timer->enable(); + } + } + else + { + // The condition did not evaluate. Stop the countdown. + timer->disable(); + } + } + + private: + /** @brief The length to wait for the condition to stop evaluating. */ + std::chrono::microseconds delayInterval; + + /** @brief Delegated timer functions. */ + std::unique_ptr<TimerType> timer; +}; + } // namespace monitoring } // namespace dbus } // namespace phosphor diff --git a/src/example/example.yaml b/src/example/example.yaml index d76e3ad..899c4c8 100644 --- a/src/example/example.yaml +++ b/src/example/example.yaml @@ -103,14 +103,13 @@ 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. + 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 + - example deferred condition - name: example count condition description: > @@ -138,3 +137,25 @@ countbound: 3 op: '>=' bound: 115 + +- name: example deferred condition + description: > + 'Deferred conditions operate in the same fashion as conditional callbacks + with the added behavior that when the condition is tested and is met, + invocation of the callback is deferred by the interval specified. + + When the configured time has elapsed, if the condition has not been reevaluated + the callback is invoked. + + Any condition type can be deferred in this way by setting the defer attribute.' + + class: condition + condition: count + paths: example path group + properties: example property group + defer: 1000us + callback: example callback group + countop: '>=' + countbound: 3 + op: '>=' + bound: 115 diff --git a/src/pdmgen.py b/src/pdmgen.py index 5d4bf29..5e88e2c 100755 --- a/src/pdmgen.py +++ b/src/pdmgen.py @@ -532,6 +532,7 @@ class ConditionCallback(ConfigEntry, Renderer): def __init__(self, *a, **kw): self.condition = kw.pop('condition') self.instance = kw.pop('instance') + self.defer = kw.pop('defer', None) super(ConditionCallback, self).__init__(**kw) def factory(self, objs): @@ -580,6 +581,7 @@ class Condition(HasPropertyIndex): def __init__(self, *a, **kw): self.callback = kw.pop('callback') + self.defer = kw.pop('defer', None) super(Condition, self).__init__(**kw) def factory(self, objs): @@ -592,6 +594,7 @@ class Condition(HasPropertyIndex): 'callback': 'conditional', 'instance': self.callback, 'name': self.name, + 'defer': self.defer } callback = ConditionCallback(**args) diff --git a/src/templates/conditional.mako.cpp b/src/templates/conditional.mako.cpp index 3cc9564..229b3d6 100644 --- a/src/templates/conditional.mako.cpp +++ b/src/templates/conditional.mako.cpp @@ -1,3 +1,10 @@ +% if c.defer: +std::make_unique<DeferrableCallback<ConfigPropertyCallbacks, SDEventTimer>>( +${indent(1)}ConfigPropertyCallbackGroups::get()[${c.graph}], +${indent(1)}*ConfigConditions::get()[${c.condition}], +${indent(1)}${c.defer})\ +% else: std::make_unique<ConditionalCallback<ConfigPropertyCallbacks>>( ${indent(1)}ConfigPropertyCallbackGroups::get()[${c.graph}], ${indent(1)}*ConfigConditions::get()[${c.condition}])\ +% endif\ diff --git a/src/templates/generated.mako.hpp b/src/templates/generated.mako.hpp index 914b065..51462b1 100644 --- a/src/templates/generated.mako.hpp +++ b/src/templates/generated.mako.hpp @@ -3,6 +3,7 @@ #pragma once #include <array> +#include <chrono> #include <string> #include "count.hpp" #include "data_types.hpp" @@ -13,6 +14,7 @@ #include "sdevent.hpp" using namespace std::string_literals; +using namespace std::chrono_literals; namespace phosphor { |