its possible to protect every read/commit now

This commit is contained in:
Robin Müller 2020-12-26 23:57:23 +01:00
parent e35c2cd604
commit 76696e34be
4 changed files with 61 additions and 6 deletions

View File

@ -9,6 +9,8 @@ PoolDataSetBase::PoolDataSetBase(PoolVariableIF** registeredVariablesArray,
PoolDataSetBase::~PoolDataSetBase() {} PoolDataSetBase::~PoolDataSetBase() {}
ReturnValue_t PoolDataSetBase::registerVariable( ReturnValue_t PoolDataSetBase::registerVariable(
PoolVariableIF *variable) { PoolVariableIF *variable) {
if (state != States::STATE_SET_UNINITIALISED) { if (state != States::STATE_SET_UNINITIALISED) {
@ -71,7 +73,13 @@ ReturnValue_t PoolDataSetBase::readVariable(uint16_t count) {
registeredVariables[count]->getDataPoolId() registeredVariables[count]->getDataPoolId()
!= PoolVariableIF::NO_PARAMETER) != PoolVariableIF::NO_PARAMETER)
{ {
result = registeredVariables[count]->readWithoutLock(); if(protectEveryReadCommitCall) {
result = registeredVariables[count]->read(mutexTimeout);
}
else {
result = registeredVariables[count]->readWithoutLock();
}
if(result != HasReturnvaluesIF::RETURN_OK) { if(result != HasReturnvaluesIF::RETURN_OK) {
result = INVALID_PARAMETER_DEFINITION; result = INVALID_PARAMETER_DEFINITION;
} }
@ -96,7 +104,12 @@ void PoolDataSetBase::handleAlreadyReadDatasetCommit(uint32_t lockTimeout) {
!= PoolVariableIF::VAR_READ != PoolVariableIF::VAR_READ
&& registeredVariables[count]->getDataPoolId() && registeredVariables[count]->getDataPoolId()
!= PoolVariableIF::NO_PARAMETER) { != PoolVariableIF::NO_PARAMETER) {
registeredVariables[count]->commitWithoutLock(); if(protectEveryReadCommitCall) {
registeredVariables[count]->commit(mutexTimeout);
}
else {
registeredVariables[count]->commitWithoutLock();
}
} }
} }
state = States::STATE_SET_UNINITIALISED; state = States::STATE_SET_UNINITIALISED;
@ -111,7 +124,13 @@ ReturnValue_t PoolDataSetBase::handleUnreadDatasetCommit(uint32_t lockTimeout) {
== PoolVariableIF::VAR_WRITE == PoolVariableIF::VAR_WRITE
&& registeredVariables[count]->getDataPoolId() && registeredVariables[count]->getDataPoolId()
!= PoolVariableIF::NO_PARAMETER) { != PoolVariableIF::NO_PARAMETER) {
registeredVariables[count]->commitWithoutLock(); if(protectEveryReadCommitCall) {
result = registeredVariables[count]->commit(mutexTimeout);
}
else {
result = registeredVariables[count]->commitWithoutLock();
}
} else if (registeredVariables[count]->getDataPoolId() } else if (registeredVariables[count]->getDataPoolId()
!= PoolVariableIF::NO_PARAMETER) { != PoolVariableIF::NO_PARAMETER) {
if (result != COMMITING_WITHOUT_READING) { if (result != COMMITING_WITHOUT_READING) {
@ -172,3 +191,9 @@ size_t PoolDataSetBase::getSerializedSize() const {
void PoolDataSetBase::setContainer(PoolVariableIF **variablesContainer) { void PoolDataSetBase::setContainer(PoolVariableIF **variablesContainer) {
this->registeredVariables = variablesContainer; this->registeredVariables = variablesContainer;
} }
void PoolDataSetBase::setReadCommitProtectionBehaviour(
bool protectEveryReadCommit, uint32_t mutexTimeout) {
this->protectEveryReadCommitCall = protectEveryReadCommit;
this->mutexTimeout = mutexTimeout;
}

View File

@ -89,6 +89,7 @@ public:
* @return * @return
*/ */
virtual ReturnValue_t registerVariable( PoolVariableIF* variable) override; virtual ReturnValue_t registerVariable( PoolVariableIF* variable) override;
/** /**
* Provides the means to lock the underlying data structure to ensure * Provides the means to lock the underlying data structure to ensure
* thread-safety. Default implementation is empty * thread-safety. Default implementation is empty
@ -114,6 +115,15 @@ public:
SerializeIF::Endianness streamEndianness) override; SerializeIF::Endianness streamEndianness) override;
protected: 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 * @brief The fill_count attribute ensures that the variables
* register in the correct array position and that the maximum * register in the correct array position and that the maximum
@ -144,6 +154,9 @@ protected:
void setContainer(PoolVariableIF** variablesContainer); void setContainer(PoolVariableIF** variablesContainer);
private: private:
bool protectEveryReadCommitCall = false;
uint32_t mutexTimeout = 20;
ReturnValue_t readVariable(uint16_t count); ReturnValue_t readVariable(uint16_t count);
void handleAlreadyReadDatasetCommit(uint32_t lockTimeout); void handleAlreadyReadDatasetCommit(uint32_t lockTimeout);
ReturnValue_t handleUnreadDatasetCommit(uint32_t lockTimeout); ReturnValue_t handleUnreadDatasetCommit(uint32_t lockTimeout);

View File

@ -8,7 +8,7 @@
LocalPoolDataSetBase::LocalPoolDataSetBase(HasLocalDataPoolIF *hkOwner, LocalPoolDataSetBase::LocalPoolDataSetBase(HasLocalDataPoolIF *hkOwner,
uint32_t setId, PoolVariableIF** registeredVariablesArray, uint32_t setId, PoolVariableIF** registeredVariablesArray,
const size_t maxNumberOfVariables, bool noPeriodicHandling): const size_t maxNumberOfVariables, bool periodicHandling):
PoolDataSetBase(registeredVariablesArray, maxNumberOfVariables) { PoolDataSetBase(registeredVariablesArray, maxNumberOfVariables) {
if(hkOwner == nullptr) { if(hkOwner == nullptr) {
// Configuration error. // Configuration error.
@ -23,7 +23,7 @@ LocalPoolDataSetBase::LocalPoolDataSetBase(HasLocalDataPoolIF *hkOwner,
mutex = MutexFactory::instance()->createMutex(); mutex = MutexFactory::instance()->createMutex();
// Data creators get a periodic helper for periodic HK data generation. // Data creators get a periodic helper for periodic HK data generation.
if(not noPeriodicHandling) { if(periodicHandling) {
periodicHelper = new PeriodicHousekeepingHelper(this); periodicHelper = new PeriodicHousekeepingHelper(this);
} }
} }
@ -278,3 +278,9 @@ void LocalPoolDataSetBase::setValidity(bool valid, bool setEntriesRecursively) {
} }
this->valid = valid; this->valid = valid;
} }
void LocalPoolDataSetBase::setReadCommitProtectionBehaviour(
bool protectEveryReadCommit, uint32_t mutexTimeout) {
PoolDataSetBase::setReadCommitProtectionBehaviour(protectEveryReadCommit,
mutexTimeout);
}

View File

@ -54,7 +54,7 @@ public:
*/ */
LocalPoolDataSetBase(HasLocalDataPoolIF *hkOwner, LocalPoolDataSetBase(HasLocalDataPoolIF *hkOwner,
uint32_t setId, PoolVariableIF** registeredVariablesArray, 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. * @brief Constructor for users of local pool data.
@ -77,6 +77,16 @@ public:
*/ */
~LocalPoolDataSetBase(); ~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); void setValidityBufferGeneration(bool withValidityBuffer);
sid_t getSid() const; sid_t getSid() const;
@ -128,6 +138,7 @@ public:
protected: protected:
sid_t sid; sid_t sid;
uint32_t mutexTimeout = 20;
MutexIF* mutex = nullptr; MutexIF* mutex = nullptr;
bool diagnostic = false; bool diagnostic = false;