110 lines
2.5 KiB
C++
110 lines
2.5 KiB
C++
/*
|
||
* FailureDiagnostics.cpp
|
||
*
|
||
* Created on: 8 окт. 2019 г.
|
||
* Author: titov
|
||
*/
|
||
|
||
#include "FailureDiagnostics.hh"
|
||
|
||
using processing::failure::FailureDiagnostics;
|
||
|
||
FailureDiagnostics::FailureDiagnostics(
|
||
FailureManagerInterface & reg, std::pmr::memory_resource * memory ) : manager(reg),
|
||
failures(Failures::allocator_type(memory)) {}
|
||
|
||
const processing::failure::FaliureInterface & FailureDiagnostics::addFailure(
|
||
systemic::IStatus & failure, FailureId id,
|
||
IFailureReset & reset ) {
|
||
|
||
std::lock_guard<std::mutex> lock(failures_lock);
|
||
|
||
failures.push_back( Failure( &failure, &reset ) );
|
||
|
||
Failure & stored_state = failures.back();
|
||
|
||
manager.registration( id, &stored_state );
|
||
|
||
return stored_state;
|
||
|
||
}
|
||
|
||
void FailureDiagnostics::process() {
|
||
|
||
bool failure_actual = false;
|
||
|
||
//todo: Use unique_lock.
|
||
if( failures_lock.try_lock() ) try {
|
||
|
||
for( Failures::iterator iter = failures.begin(); iter != failures.end(); ++iter )
|
||
if( iter->check() and not failure_actual ) {
|
||
failure_actual = true;
|
||
manager.fault();
|
||
}
|
||
|
||
failures_lock.unlock();
|
||
|
||
} catch(...) {
|
||
|
||
failures_lock.unlock();
|
||
throw;
|
||
|
||
}
|
||
|
||
}
|
||
|
||
|
||
bool FailureDiagnostics::Failure::check() {
|
||
failure_actual = *failure;
|
||
|
||
if( not failure_stored and failure_actual )
|
||
failure_ticket = true;
|
||
|
||
failure_stored |= failure_actual;
|
||
|
||
return failure_actual;
|
||
}
|
||
|
||
bool FailureDiagnostics::Failure::stored() const {
|
||
return failure_stored;
|
||
}
|
||
|
||
bool FailureDiagnostics::Failure::actual() const {
|
||
return failure_actual;
|
||
}
|
||
|
||
FailureDiagnostics::Failure::Failure(
|
||
systemic::IStatus * failure, IFailureReset * reset ) : failure(failure), reset(reset),
|
||
failure_stored(false), failure_actual(false), failure_ticket(false) {}
|
||
|
||
bool FailureDiagnostics::Failure::acknowledge() {
|
||
|
||
if( failure_actual and (*reset)() )
|
||
failure_actual = false;
|
||
|
||
if( failure_stored and not failure_actual )
|
||
failure_stored = failure_actual;
|
||
|
||
return not failure_stored;
|
||
|
||
}
|
||
|
||
|
||
FailureDiagnostics::IFailureReset & FailureDiagnostics::getDefaultReset() {
|
||
static struct DefaultCallbackAcknowledge : public IFailureReset {
|
||
bool operator()() { return false; }
|
||
} default_ack;
|
||
|
||
return default_ack;
|
||
}
|
||
|
||
bool processing::failure::FailureDiagnostics::Failure::ticket() {
|
||
|
||
bool ticket_state = failure_ticket;
|
||
|
||
failure_ticket = false;
|
||
|
||
return ticket_state;
|
||
|
||
}
|