Module: check_mk
Branch: master
Commit: a6dcef8c1fe4ddb7d413bd61be4be3e1baf2cbcf
URL:
http://git.mathias-kettner.de/git/?p=check_mk.git;a=commit;h=a6dcef8c1fe4dd…
Author: Sven Panne <sp(a)mathias-kettner.de>
Date: Tue Nov 14 09:51:34 2017 +0100
Refactored wait triggers a bit, improving typing on the way.
Change-Id: Ie4d4e0b17b5dba624a2a1a84fa6977e4ce900001
---
livestatus/src/Query.cc | 54 +++++++++++++++++++-----------------------
livestatus/src/Query.h | 4 +++-
livestatus/src/waittriggers.cc | 43 +++++++++++++--------------------
livestatus/src/waittriggers.h | 5 +++-
4 files changed, 49 insertions(+), 57 deletions(-)
diff --git a/livestatus/src/Query.cc b/livestatus/src/Query.cc
index 9b2658a..65573e8 100644
--- a/livestatus/src/Query.cc
+++ b/livestatus/src/Query.cc
@@ -629,7 +629,7 @@ void Query::parseWaitTimeoutLine(char *line) {
invalidHeader(
"Invalid value for WaitTimeout: must be non-negative
integer");
} else {
- _wait_timeout = timeout;
+ _wait_timeout = std::chrono::milliseconds(timeout);
}
}
}
@@ -850,38 +850,34 @@ const std::vector<std::unique_ptr<Aggregator>>
&Query::getAggregatorsFor(
}
void Query::doWait() {
- // If no wait condition and no trigger is set,
- // we do not wait at all.
- if (_wait_conditions_empty && _wait_trigger == nullptr) {
+ // TODO(sp): Funny special case, do we really want/need this?
+ if (_wait_conditions_empty && _wait_trigger != nullptr) {
+ waitForTrigger();
return;
}
- // If a condition is set, we check the condition. If it
- // is already true, we do not need to way
- if (!_wait_conditions_empty &&
- _wait_condition->accepts(_wait_object, _auth_user, timezoneOffset())) {
- Debug(_logger) << "Wait condition true, no waiting neccessary";
- return;
+ // Starting from here, it's basically a standard condition variable.
+ while (
+ !_wait_condition->accepts(_wait_object, _auth_user, timezoneOffset())) {
+ if (waitForTrigger() == std::cv_status::timeout) {
+ return;
+ }
}
+}
- // No wait on specified trigger. If no trigger was specified
- // we use WT_ALL as default trigger.
- if (_wait_trigger == nullptr) {
- _wait_trigger = trigger_all();
+std::cv_status Query::waitForTrigger() const {
+ auto trigger = _wait_trigger == nullptr ? trigger_all() : _wait_trigger;
+ if (_wait_timeout == std::chrono::milliseconds(0)) {
+ Debug(_logger) << "waiting until condition becomes true";
+ trigger_wait(trigger);
+ return std::cv_status::no_timeout;
}
-
- do {
- if (_wait_timeout == 0) {
- Debug(_logger) << "Waiting unlimited until condition becomes
true";
- trigger_wait(_wait_trigger);
- } else {
- Debug(_logger) << "Waiting " << _wait_timeout
- << "ms or until condition becomes true";
- if (trigger_wait_for(_wait_trigger, _wait_timeout) == 0) {
- Debug(_logger) << "WaitTimeout after " <<
_wait_timeout << "ms";
- return; // timeout occurred. do not wait any longer
- }
- }
- } while (
- !_wait_condition->accepts(_wait_object, _auth_user, timezoneOffset()));
+ Debug(_logger) << "waiting " << _wait_timeout.count()
+ << "ms or until condition becomes true";
+ auto status = trigger_wait_for(trigger, _wait_timeout);
+ if (status == std::cv_status::timeout) {
+ Debug(_logger) << "wait timeout after " <<
_wait_timeout.count()
+ << "ms";
+ }
+ return status;
}
diff --git a/livestatus/src/Query.h b/livestatus/src/Query.h
index 604726f..ea1a12b 100644
--- a/livestatus/src/Query.h
+++ b/livestatus/src/Query.h
@@ -27,6 +27,7 @@
#include "config.h" // IWYU pragma: keep
#include <chrono>
+#include <condition_variable>
#include <cstdint>
#include <ctime>
#include <list>
@@ -92,7 +93,7 @@ private:
contact *_auth_user;
bool _wait_conditions_empty; // TODO(sp): HACK, remove me...
std::unique_ptr<AndingFilter> _wait_condition;
- unsigned _wait_timeout;
+ std::chrono::milliseconds _wait_timeout;
struct trigger *_wait_trigger;
Row _wait_object;
CSVSeparators _separators;
@@ -115,6 +116,7 @@ private:
bool doStats() const;
void doWait();
+ std::cv_status waitForTrigger() const;
std::unique_ptr<Filter> createFilter(const Column &column,
RelationalOperator relOp,
const std::string &value);
diff --git a/livestatus/src/waittriggers.cc b/livestatus/src/waittriggers.cc
index 56a9a97..fba3b0a 100644
--- a/livestatus/src/waittriggers.cc
+++ b/livestatus/src/waittriggers.cc
@@ -23,38 +23,29 @@
// Boston, MA 02110-1301 USA.
#include "waittriggers.h"
-#include <chrono>
-#include <condition_variable>
#include <cstring>
#include <mutex>
#include <ratio>
-using std::chrono::milliseconds;
-using std::condition_variable;
-using std::cv_status;
-using std::mutex;
-using std::unique_lock;
-
namespace {
-
-struct trigger *to_trigger(condition_variable *c) {
+struct trigger *to_trigger(std::condition_variable *c) {
return reinterpret_cast<struct trigger *>(c);
}
-condition_variable *from_trigger(struct trigger *c) {
- return reinterpret_cast<condition_variable *>(c);
+std::condition_variable *from_trigger(struct trigger *c) {
+ return reinterpret_cast<std::condition_variable *>(c);
}
-mutex wait_mutex;
+std::mutex wait_mutex;
-condition_variable cond_all;
-condition_variable cond_check;
-condition_variable cond_state;
-condition_variable cond_log;
-condition_variable cond_downtime;
-condition_variable cond_comment;
-condition_variable cond_command;
-condition_variable cond_program;
+std::condition_variable cond_all;
+std::condition_variable cond_check;
+std::condition_variable cond_state;
+std::condition_variable cond_log;
+std::condition_variable cond_downtime;
+std::condition_variable cond_comment;
+std::condition_variable cond_command;
+std::condition_variable cond_program;
} // namespace
struct trigger *trigger_all() {
@@ -127,12 +118,12 @@ void trigger_notify_all(struct trigger *which) {
}
void trigger_wait(struct trigger *which) {
- unique_lock<mutex> ul(wait_mutex);
+ std::unique_lock<std::mutex> ul(wait_mutex);
from_trigger(which)->wait(ul);
}
-int trigger_wait_for(struct trigger *which, unsigned ms) {
- unique_lock<mutex> ul(wait_mutex);
- return static_cast<int>(from_trigger(which)->wait_for(
- ul, milliseconds(ms)) == cv_status::no_timeout);
+std::cv_status trigger_wait_for(struct trigger *which,
+ std::chrono::milliseconds ms) {
+ std::unique_lock<std::mutex> ul(wait_mutex);
+ return from_trigger(which)->wait_for(ul, ms);
}
diff --git a/livestatus/src/waittriggers.h b/livestatus/src/waittriggers.h
index 83f2171..eb872b1 100644
--- a/livestatus/src/waittriggers.h
+++ b/livestatus/src/waittriggers.h
@@ -26,6 +26,8 @@
#define waittriggers_h
#include "config.h" // IWYU pragma: keep
+#include <chrono>
+#include <condition_variable>
// This is basically a C++ class for triggers done the "C way" via an opaque
// struct, explicit passing of 'this' and using a prefix for names.
@@ -46,6 +48,7 @@ const char *trigger_all_names();
void trigger_notify_all(struct trigger *which);
void trigger_wait(struct trigger *which);
-int trigger_wait_for(struct trigger *which, unsigned ms);
+std::cv_status trigger_wait_for(struct trigger *which,
+ std::chrono::milliseconds ms);
#endif // waittriggers_h