mirror of
https://gitlab.isc.org/isc-projects/kea
synced 2025-09-03 23:45:27 +00:00
[#1095] Made state model code thread safe
This commit is contained in:
committed by
Razvan Becheriu
parent
de0bafbfed
commit
4c7746d5cf
@@ -1,4 +1,4 @@
|
|||||||
// Copyright (C) 2013-2018 Internet Systems Consortium, Inc. ("ISC")
|
// Copyright (C) 2013-2020 Internet Systems Consortium, Inc. ("ISC")
|
||||||
//
|
//
|
||||||
// This Source Code Form is subject to the terms of the Mozilla Public
|
// This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
// License, v. 2.0. If a copy of the MPL was not distributed with this
|
// License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
@@ -91,7 +91,7 @@ StateModel::StateModel() : events_(), states_(), dictionaries_initted_(false),
|
|||||||
curr_state_(NEW_ST), prev_state_(NEW_ST),
|
curr_state_(NEW_ST), prev_state_(NEW_ST),
|
||||||
last_event_(NOP_EVT), next_event_(NOP_EVT),
|
last_event_(NOP_EVT), next_event_(NOP_EVT),
|
||||||
on_entry_flag_(false), on_exit_flag_(false),
|
on_entry_flag_(false), on_exit_flag_(false),
|
||||||
paused_(false) {
|
paused_(false), mutex_(new std::mutex) {
|
||||||
}
|
}
|
||||||
|
|
||||||
StateModel::~StateModel(){
|
StateModel::~StateModel(){
|
||||||
@@ -279,6 +279,7 @@ StateModel::abortModel(const std::string& explanation) {
|
|||||||
|
|
||||||
void
|
void
|
||||||
StateModel::setState(unsigned int state) {
|
StateModel::setState(unsigned int state) {
|
||||||
|
std::lock_guard<std::mutex> lock(*mutex_);
|
||||||
if (state != END_ST && !states_.isDefined(state)) {
|
if (state != END_ST && !states_.isDefined(state)) {
|
||||||
isc_throw(StateModelError,
|
isc_throw(StateModelError,
|
||||||
"Attempt to set state to an undefined value: " << state );
|
"Attempt to set state to an undefined value: " << state );
|
||||||
@@ -309,6 +310,7 @@ StateModel::postNextEvent(unsigned int event_value) {
|
|||||||
"Attempt to post an undefined event, value: " << event_value);
|
"Attempt to post an undefined event, value: " << event_value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::lock_guard<std::mutex> lock(*mutex_);
|
||||||
last_event_ = next_event_;
|
last_event_ = next_event_;
|
||||||
next_event_ = event_value;
|
next_event_ = event_value;
|
||||||
}
|
}
|
||||||
@@ -329,50 +331,61 @@ StateModel::doOnExit() {
|
|||||||
|
|
||||||
unsigned int
|
unsigned int
|
||||||
StateModel::getCurrState() const {
|
StateModel::getCurrState() const {
|
||||||
|
std::lock_guard<std::mutex> lock(*mutex_);
|
||||||
return (curr_state_);
|
return (curr_state_);
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned int
|
unsigned int
|
||||||
StateModel::getPrevState() const {
|
StateModel::getPrevState() const {
|
||||||
|
std::lock_guard<std::mutex> lock(*mutex_);
|
||||||
return (prev_state_);
|
return (prev_state_);
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned int
|
unsigned int
|
||||||
StateModel::getLastEvent() const {
|
StateModel::getLastEvent() const {
|
||||||
|
std::lock_guard<std::mutex> lock(*mutex_);
|
||||||
return (last_event_);
|
return (last_event_);
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned int
|
unsigned int
|
||||||
StateModel::getNextEvent() const {
|
StateModel::getNextEvent() const {
|
||||||
|
std::lock_guard<std::mutex> lock(*mutex_);
|
||||||
return (next_event_);
|
return (next_event_);
|
||||||
}
|
}
|
||||||
bool
|
bool
|
||||||
StateModel::isModelNew() const {
|
StateModel::isModelNew() const {
|
||||||
|
std::lock_guard<std::mutex> lock(*mutex_);
|
||||||
return (curr_state_ == NEW_ST);
|
return (curr_state_ == NEW_ST);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
StateModel::isModelRunning() const {
|
StateModel::isModelRunning() const {
|
||||||
|
std::lock_guard<std::mutex> lock(*mutex_);
|
||||||
return ((curr_state_ != NEW_ST) && (curr_state_ != END_ST));
|
return ((curr_state_ != NEW_ST) && (curr_state_ != END_ST));
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
StateModel::isModelWaiting() const {
|
StateModel::isModelWaiting() const {
|
||||||
return (isModelRunning() && (next_event_ == NOP_EVT));
|
std::lock_guard<std::mutex> lock(*mutex_);
|
||||||
|
return ((curr_state_ != NEW_ST) && (curr_state_ != END_ST) &&
|
||||||
|
(next_event_ == NOP_EVT));
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
StateModel::isModelDone() const {
|
StateModel::isModelDone() const {
|
||||||
|
std::lock_guard<std::mutex> lock(*mutex_);
|
||||||
return (curr_state_ == END_ST);
|
return (curr_state_ == END_ST);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
StateModel::didModelFail() const {
|
StateModel::didModelFail() const {
|
||||||
return (isModelDone() && (next_event_ == FAIL_EVT));
|
std::lock_guard<std::mutex> lock(*mutex_);
|
||||||
|
return ((curr_state_ == END_ST) && (next_event_ == FAIL_EVT));
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
StateModel::isModelPaused() const {
|
StateModel::isModelPaused() const {
|
||||||
|
std::lock_guard<std::mutex> lock(*mutex_);
|
||||||
return (paused_);
|
return (paused_);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -388,6 +401,7 @@ StateModel::getEventLabel(const int event) const {
|
|||||||
|
|
||||||
std::string
|
std::string
|
||||||
StateModel::getContextStr() const {
|
StateModel::getContextStr() const {
|
||||||
|
std::lock_guard<std::mutex> lock(*mutex_);
|
||||||
std::ostringstream stream;
|
std::ostringstream stream;
|
||||||
stream << "current state: [ "
|
stream << "current state: [ "
|
||||||
<< curr_state_ << " " << getStateLabel(curr_state_)
|
<< curr_state_ << " " << getStateLabel(curr_state_)
|
||||||
@@ -398,6 +412,7 @@ StateModel::getContextStr() const {
|
|||||||
|
|
||||||
std::string
|
std::string
|
||||||
StateModel::getPrevContextStr() const {
|
StateModel::getPrevContextStr() const {
|
||||||
|
std::lock_guard<std::mutex> lock(*mutex_);
|
||||||
std::ostringstream stream;
|
std::ostringstream stream;
|
||||||
stream << "previous state: [ "
|
stream << "previous state: [ "
|
||||||
<< prev_state_ << " " << getStateLabel(prev_state_)
|
<< prev_state_ << " " << getStateLabel(prev_state_)
|
||||||
|
@@ -1,4 +1,4 @@
|
|||||||
// Copyright (C) 2013-2018 Internet Systems Consortium, Inc. ("ISC")
|
// Copyright (C) 2013-2020 Internet Systems Consortium, Inc. ("ISC")
|
||||||
//
|
//
|
||||||
// This Source Code Form is subject to the terms of the Mozilla Public
|
// This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
// License, v. 2.0. If a copy of the MPL was not distributed with this
|
// License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
@@ -14,6 +14,7 @@
|
|||||||
#include <boost/function.hpp>
|
#include <boost/function.hpp>
|
||||||
#include <boost/shared_ptr.hpp>
|
#include <boost/shared_ptr.hpp>
|
||||||
#include <map>
|
#include <map>
|
||||||
|
#include <mutex>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
namespace isc {
|
namespace isc {
|
||||||
@@ -721,6 +722,9 @@ private:
|
|||||||
|
|
||||||
/// @brief Indicates if the state model is paused.
|
/// @brief Indicates if the state model is paused.
|
||||||
bool paused_;
|
bool paused_;
|
||||||
|
|
||||||
|
/// @brief Protects against concurrent transitions.
|
||||||
|
boost::shared_ptr<std::mutex> mutex_;
|
||||||
};
|
};
|
||||||
|
|
||||||
/// @brief Defines a pointer to a StateModel.
|
/// @brief Defines a pointer to a StateModel.
|
||||||
|
Reference in New Issue
Block a user