File tree 4 files changed +89
-2
lines changed
4 files changed +89
-2
lines changed Original file line number Diff line number Diff line change @@ -60,6 +60,7 @@ void CheckerComponent::OnConfigLoaded()
60
60
void CheckerComponent::Start (bool runtimeCreated)
61
61
{
62
62
ObjectImpl<CheckerComponent>::Start (runtimeCreated);
63
+ CheckResultProducerComponent::Start ();
63
64
64
65
Log (LogInformation, " CheckerComponent" )
65
66
<< " '" << GetName () << " ' started." ;
@@ -81,6 +82,7 @@ void CheckerComponent::Stop(bool runtimeRemoved)
81
82
m_CV.notify_all ();
82
83
}
83
84
85
+ CheckResultProducerComponent::Stop ();
84
86
m_ResultTimer->Stop (true );
85
87
m_Thread.join ();
86
88
@@ -232,7 +234,7 @@ void CheckerComponent::ExecuteCheckHelper(const Checkable::Ptr& checkable)
232
234
try {
233
235
checkable->ExecuteCheck ();
234
236
} catch (const std::exception & ex) {
235
- CheckResult::Ptr cr = new CheckResult ();
237
+ CheckResult::Ptr cr = new CheckResult (this );
236
238
cr->SetState (ServiceUnknown);
237
239
238
240
String output = " Exception occurred while checking '" + checkable->GetName () + " ': " + DiagnosticInformation (ex);
Original file line number Diff line number Diff line change @@ -46,7 +46,7 @@ struct CheckableNextCheckExtractor
46
46
/* *
47
47
* @ingroup checker
48
48
*/
49
- class CheckerComponent final : public ObjectImpl<CheckerComponent>
49
+ class CheckerComponent final : public ObjectImpl<CheckerComponent>, public CheckResultProducerComponent
50
50
{
51
51
public:
52
52
DECLARE_OBJECT (CheckerComponent);
Original file line number Diff line number Diff line change @@ -33,6 +33,51 @@ double CheckResult::CalculateLatency() const
33
33
return latency;
34
34
}
35
35
36
+ bool CheckResultProducerComponent::try_lock_shared () noexcept
37
+ {
38
+ auto expected (m_State.load ());
39
+ decltype (expected) desired;
40
+
41
+ do {
42
+ if (!expected.m_InstanceIsActive ) {
43
+ return false ;
44
+ }
45
+
46
+ desired = expected;
47
+ ++desired.m_ProcessingCheckResults ;
48
+ } while (!m_State.compare_exchange_weak (expected, desired));
49
+
50
+ return true ;
51
+ }
52
+
53
+ void CheckResultProducerComponent::unlock_shared () noexcept
54
+ {
55
+ auto state (ModifyState ([](auto & desired) { --desired.m_ProcessingCheckResults ; }));
56
+
57
+ if (!state.m_ProcessingCheckResults ) {
58
+ m_CV.notify_all ();
59
+ }
60
+ }
61
+
62
+ /* *
63
+ * Allow processing check results.
64
+ */
65
+ void CheckResultProducerComponent::Start ()
66
+ {
67
+ ModifyState ([](auto & desired) { desired.m_InstanceIsActive = 1 ; });
68
+ }
69
+
70
+ /* *
71
+ * Disallow processing new check results, wait for all currently processed ones to finish.
72
+ */
73
+ void CheckResultProducerComponent::Stop ()
74
+ {
75
+ ModifyState ([](auto & desired) { desired.m_InstanceIsActive = 0 ; });
76
+
77
+ std::unique_lock lock (m_Mutex);
78
+ m_CV.wait (lock, [this ] { return !m_State.load ().m_ProcessingCheckResults ; });
79
+ }
80
+
36
81
ObjectFactory TypeHelper<CheckResult, false >::GetFactory()
37
82
{
38
83
return &Factory;
Original file line number Diff line number Diff line change 3
3
#ifndef CHECKRESULT_H
4
4
#define CHECKRESULT_H
5
5
6
+ #include " base/atomic.hpp"
6
7
#include " icinga/i2-icinga.hpp"
7
8
#include " icinga/checkresult-ti.hpp"
9
+ #include < condition_variable>
10
+ #include < cstdint>
11
+ #include < mutex>
8
12
#include < utility>
9
13
10
14
namespace icinga
@@ -60,6 +64,42 @@ class CheckResult final : public ObjectImpl<CheckResult>
60
64
CheckResultProducer::Ptr m_Producer;
61
65
};
62
66
67
+ class CheckResultProducerComponent : public CheckResultProducer
68
+ {
69
+ public:
70
+ bool try_lock_shared () noexcept override ;
71
+ void unlock_shared () noexcept override ;
72
+
73
+ protected:
74
+ void Start ();
75
+ void Stop ();
76
+
77
+ private:
78
+ struct State
79
+ {
80
+ uint32_t m_InstanceIsActive = 0 ;
81
+ uint32_t m_ProcessingCheckResults = 0 ;
82
+ };
83
+
84
+ Atomic<State> m_State {State{}};
85
+ std::mutex m_Mutex;
86
+ std::condition_variable m_CV;
87
+
88
+ template <class F >
89
+ State ModifyState (const F& func)
90
+ {
91
+ auto expected (m_State.load ());
92
+ decltype (expected) desired;
93
+
94
+ do {
95
+ desired = expected;
96
+ func (desired);
97
+ } while (!m_State.compare_exchange_weak (expected, desired));
98
+
99
+ return desired;
100
+ }
101
+ };
102
+
63
103
template <>
64
104
struct TypeHelper <CheckResult, false >
65
105
{
You can’t perform that action at this time.
0 commit comments