]> git.ipfire.org Git - thirdparty/kea.git/commitdiff
[#1095] Made state model code thread safe
authorFrancis Dupont <fdupont@isc.org>
Sat, 28 Mar 2020 14:58:55 +0000 (15:58 +0100)
committerRazvan Becheriu <razvan@isc.org>
Wed, 6 May 2020 09:46:31 +0000 (12:46 +0300)
src/lib/util/state_model.cc
src/lib/util/state_model.h

index 38ac9d73f1ff9b7179b55339d35c47ca668f306b..f4b511a653a3f46054091a63bdbbc731e7bb9b23 100644 (file)
@@ -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
 // 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),
                            last_event_(NOP_EVT), next_event_(NOP_EVT),
                            on_entry_flag_(false), on_exit_flag_(false),
-                           paused_(false) {
+                           paused_(false), mutex_(new std::mutex) {
 }
 
 StateModel::~StateModel(){
@@ -279,6 +279,7 @@ StateModel::abortModel(const std::string& explanation) {
 
 void
 StateModel::setState(unsigned int state) {
+    std::lock_guard<std::mutex> lock(*mutex_);
     if (state != END_ST && !states_.isDefined(state)) {
         isc_throw(StateModelError,
                   "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);
     }
 
+    std::lock_guard<std::mutex> lock(*mutex_);
     last_event_ = next_event_;
     next_event_ = event_value;
 }
@@ -329,50 +331,61 @@ StateModel::doOnExit() {
 
 unsigned int
 StateModel::getCurrState() const {
+    std::lock_guard<std::mutex> lock(*mutex_);
     return (curr_state_);
 }
 
 unsigned int
 StateModel::getPrevState() const {
+    std::lock_guard<std::mutex> lock(*mutex_);
     return (prev_state_);
 }
 
 unsigned int
 StateModel::getLastEvent() const {
+    std::lock_guard<std::mutex> lock(*mutex_);
     return (last_event_);
 }
 
 unsigned int
 StateModel::getNextEvent() const {
+    std::lock_guard<std::mutex> lock(*mutex_);
     return (next_event_);
 }
 bool
 StateModel::isModelNew() const {
+    std::lock_guard<std::mutex> lock(*mutex_);
     return (curr_state_ == NEW_ST);
 }
 
 bool
 StateModel::isModelRunning() const {
+    std::lock_guard<std::mutex> lock(*mutex_);
     return ((curr_state_ != NEW_ST) && (curr_state_ != END_ST));
 }
 
 bool
 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
 StateModel::isModelDone() const {
+    std::lock_guard<std::mutex> lock(*mutex_);
     return (curr_state_ == END_ST);
 }
 
 bool
 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
 StateModel::isModelPaused() const {
+    std::lock_guard<std::mutex> lock(*mutex_);
     return (paused_);
 }
 
@@ -388,6 +401,7 @@ StateModel::getEventLabel(const int event) const {
 
 std::string
 StateModel::getContextStr() const {
+    std::lock_guard<std::mutex> lock(*mutex_);
     std::ostringstream stream;
     stream << "current state: [ "
             << curr_state_ << " " << getStateLabel(curr_state_)
@@ -398,6 +412,7 @@ StateModel::getContextStr() const {
 
 std::string
 StateModel::getPrevContextStr() const {
+    std::lock_guard<std::mutex> lock(*mutex_);
     std::ostringstream stream;
     stream << "previous state: [ "
            << prev_state_ << " " << getStateLabel(prev_state_)
index 0299dbaebc423dc2472c364e3781bd81b06f2e3e..7f487b88de34f1ffc2121401abefe96e3f3b34c5 100644 (file)
@@ -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
 // 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/shared_ptr.hpp>
 #include <map>
+#include <mutex>
 #include <string>
 
 namespace isc {
@@ -721,6 +722,9 @@ private:
 
     /// @brief Indicates if the state model is paused.
     bool paused_;
+
+    /// @brief Protects against concurrent transitions.
+    boost::shared_ptr<std::mutex> mutex_;
 };
 
 /// @brief Defines a pointer to a StateModel.