From 76696e34be711277fdbdd07575380f1e2b294a17 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Sat, 26 Dec 2020 23:57:23 +0100 Subject: [PATCH] its possible to protect every read/commit now --- datapool/PoolDataSetBase.cpp | 31 +++++++++++++++++++++++--- datapool/PoolDataSetBase.h | 13 +++++++++++ datapoollocal/LocalPoolDataSetBase.cpp | 10 +++++++-- datapoollocal/LocalPoolDataSetBase.h | 13 ++++++++++- 4 files changed, 61 insertions(+), 6 deletions(-) diff --git a/datapool/PoolDataSetBase.cpp b/datapool/PoolDataSetBase.cpp index 49495a88..ad1de8e4 100644 --- a/datapool/PoolDataSetBase.cpp +++ b/datapool/PoolDataSetBase.cpp @@ -9,6 +9,8 @@ PoolDataSetBase::PoolDataSetBase(PoolVariableIF** registeredVariablesArray, PoolDataSetBase::~PoolDataSetBase() {} + + ReturnValue_t PoolDataSetBase::registerVariable( PoolVariableIF *variable) { if (state != States::STATE_SET_UNINITIALISED) { @@ -71,7 +73,13 @@ ReturnValue_t PoolDataSetBase::readVariable(uint16_t count) { registeredVariables[count]->getDataPoolId() != PoolVariableIF::NO_PARAMETER) { - result = registeredVariables[count]->readWithoutLock(); + if(protectEveryReadCommitCall) { + result = registeredVariables[count]->read(mutexTimeout); + } + else { + result = registeredVariables[count]->readWithoutLock(); + } + if(result != HasReturnvaluesIF::RETURN_OK) { result = INVALID_PARAMETER_DEFINITION; } @@ -96,7 +104,12 @@ void PoolDataSetBase::handleAlreadyReadDatasetCommit(uint32_t lockTimeout) { != PoolVariableIF::VAR_READ && registeredVariables[count]->getDataPoolId() != PoolVariableIF::NO_PARAMETER) { - registeredVariables[count]->commitWithoutLock(); + if(protectEveryReadCommitCall) { + registeredVariables[count]->commit(mutexTimeout); + } + else { + registeredVariables[count]->commitWithoutLock(); + } } } state = States::STATE_SET_UNINITIALISED; @@ -111,7 +124,13 @@ ReturnValue_t PoolDataSetBase::handleUnreadDatasetCommit(uint32_t lockTimeout) { == PoolVariableIF::VAR_WRITE && registeredVariables[count]->getDataPoolId() != PoolVariableIF::NO_PARAMETER) { - registeredVariables[count]->commitWithoutLock(); + if(protectEveryReadCommitCall) { + result = registeredVariables[count]->commit(mutexTimeout); + } + else { + result = registeredVariables[count]->commitWithoutLock(); + } + } else if (registeredVariables[count]->getDataPoolId() != PoolVariableIF::NO_PARAMETER) { if (result != COMMITING_WITHOUT_READING) { @@ -172,3 +191,9 @@ size_t PoolDataSetBase::getSerializedSize() const { void PoolDataSetBase::setContainer(PoolVariableIF **variablesContainer) { this->registeredVariables = variablesContainer; } + +void PoolDataSetBase::setReadCommitProtectionBehaviour( + bool protectEveryReadCommit, uint32_t mutexTimeout) { + this->protectEveryReadCommitCall = protectEveryReadCommit; + this->mutexTimeout = mutexTimeout; +} diff --git a/datapool/PoolDataSetBase.h b/datapool/PoolDataSetBase.h index 66a1924c..3f52fcd0 100644 --- a/datapool/PoolDataSetBase.h +++ b/datapool/PoolDataSetBase.h @@ -89,6 +89,7 @@ public: * @return */ virtual ReturnValue_t registerVariable( PoolVariableIF* variable) override; + /** * Provides the means to lock the underlying data structure to ensure * thread-safety. Default implementation is empty @@ -114,6 +115,15 @@ public: SerializeIF::Endianness streamEndianness) override; protected: + + /** + * Can be used to individually protect every read and commit call. + * @param protectEveryReadCommit + * @param mutexTimeout + */ + void setReadCommitProtectionBehaviour(bool protectEveryReadCommit, + uint32_t mutexTimeout = 20); + /** * @brief The fill_count attribute ensures that the variables * register in the correct array position and that the maximum @@ -144,6 +154,9 @@ protected: void setContainer(PoolVariableIF** variablesContainer); private: + bool protectEveryReadCommitCall = false; + uint32_t mutexTimeout = 20; + ReturnValue_t readVariable(uint16_t count); void handleAlreadyReadDatasetCommit(uint32_t lockTimeout); ReturnValue_t handleUnreadDatasetCommit(uint32_t lockTimeout); diff --git a/datapoollocal/LocalPoolDataSetBase.cpp b/datapoollocal/LocalPoolDataSetBase.cpp index dc81a612..9ecad218 100644 --- a/datapoollocal/LocalPoolDataSetBase.cpp +++ b/datapoollocal/LocalPoolDataSetBase.cpp @@ -8,7 +8,7 @@ LocalPoolDataSetBase::LocalPoolDataSetBase(HasLocalDataPoolIF *hkOwner, uint32_t setId, PoolVariableIF** registeredVariablesArray, - const size_t maxNumberOfVariables, bool noPeriodicHandling): + const size_t maxNumberOfVariables, bool periodicHandling): PoolDataSetBase(registeredVariablesArray, maxNumberOfVariables) { if(hkOwner == nullptr) { // Configuration error. @@ -23,7 +23,7 @@ LocalPoolDataSetBase::LocalPoolDataSetBase(HasLocalDataPoolIF *hkOwner, mutex = MutexFactory::instance()->createMutex(); // Data creators get a periodic helper for periodic HK data generation. - if(not noPeriodicHandling) { + if(periodicHandling) { periodicHelper = new PeriodicHousekeepingHelper(this); } } @@ -278,3 +278,9 @@ void LocalPoolDataSetBase::setValidity(bool valid, bool setEntriesRecursively) { } this->valid = valid; } + +void LocalPoolDataSetBase::setReadCommitProtectionBehaviour( + bool protectEveryReadCommit, uint32_t mutexTimeout) { + PoolDataSetBase::setReadCommitProtectionBehaviour(protectEveryReadCommit, + mutexTimeout); +} diff --git a/datapoollocal/LocalPoolDataSetBase.h b/datapoollocal/LocalPoolDataSetBase.h index aa155bf1..7eabd368 100644 --- a/datapoollocal/LocalPoolDataSetBase.h +++ b/datapoollocal/LocalPoolDataSetBase.h @@ -54,7 +54,7 @@ public: */ LocalPoolDataSetBase(HasLocalDataPoolIF *hkOwner, uint32_t setId, PoolVariableIF** registeredVariablesArray, - const size_t maxNumberOfVariables, bool noPeriodicHandling = false); + const size_t maxNumberOfVariables, bool periodicHandling = true); /** * @brief Constructor for users of local pool data. @@ -77,6 +77,16 @@ public: */ ~LocalPoolDataSetBase(); + /** + * If the data is pulled from different local data pools, every read and + * commit call should be mutex protected for thread safety. + * This can be specified with the second parameter. + * @param dataCreator + * @param protectEveryReadCommit + */ + void setReadCommitProtectionBehaviour(bool protectEveryReadCommit, + uint32_t mutexTimeout = 20); + void setValidityBufferGeneration(bool withValidityBuffer); sid_t getSid() const; @@ -128,6 +138,7 @@ public: protected: sid_t sid; + uint32_t mutexTimeout = 20; MutexIF* mutex = nullptr; bool diagnostic = false;