commented out storage accessor

This commit is contained in:
Robin Müller 2020-05-10 00:14:00 +02:00
parent 0f286461d0
commit 2f58c3a305
2 changed files with 328 additions and 328 deletions

View File

@ -1,154 +1,154 @@
#include <test/prototypes/StorageAccessor.h> //#include <framework/storagemanager/StorageAccessor.h>
//
ConstStorageAccessor::ConstStorageAccessor(store_address_t storeId): storeId(storeId) {} //ConstStorageAccessor::ConstStorageAccessor(store_address_t storeId): storeId(storeId) {}
//
ConstStorageAccessor::~ConstStorageAccessor() { //ConstStorageAccessor::~ConstStorageAccessor() {
if(deleteData and store != nullptr) { // if(deleteData and store != nullptr) {
sif::debug << "deleting store data" << std::endl; // sif::debug << "deleting store data" << std::endl;
store->deleteDataNonLocking(storeId); // store->deleteDataNonLocking(storeId);
} // }
if(mutexLock != nullptr) { // if(mutexLock != nullptr) {
sif::debug << "unlocking mutex lock" << std::endl; // sif::debug << "unlocking mutex lock" << std::endl;
mutexLock.reset(); // mutexLock.reset();
} // }
} //}
//
ConstStorageAccessor& ConstStorageAccessor::operator=( //ConstStorageAccessor& ConstStorageAccessor::operator=(
ConstStorageAccessor&& other) { // ConstStorageAccessor&& other) {
constDataPointer = other.constDataPointer; // constDataPointer = other.constDataPointer;
storeId = other.storeId; // storeId = other.storeId;
store = other.store; // store = other.store;
size_ = other.size_; // size_ = other.size_;
deleteData = other.deleteData; // deleteData = other.deleteData;
this->store = other.store; // this->store = other.store;
// Transfer ownership of the lock. // // Transfer ownership of the lock.
mutexLock = std::move(other.mutexLock); // mutexLock = std::move(other.mutexLock);
// This prevents double deletion of the resource // // This prevents double deletion of the resource
other.mutexLock = nullptr; // other.mutexLock = nullptr;
// This prevent premature deletion // // This prevent premature deletion
other.store = nullptr; // other.store = nullptr;
return *this; // return *this;
} //}
//
StorageAccessor::StorageAccessor(store_address_t storeId): //StorageAccessor::StorageAccessor(store_address_t storeId):
ConstStorageAccessor(storeId) { // ConstStorageAccessor(storeId) {
} //}
//
StorageAccessor& StorageAccessor::operator =( //StorageAccessor& StorageAccessor::operator =(
StorageAccessor&& other) { // StorageAccessor&& other) {
// Call the parent move assignment and also assign own member. // // Call the parent move assignment and also assign own member.
dataPointer = other.dataPointer; // dataPointer = other.dataPointer;
StorageAccessor::operator=(std::move(other)); // StorageAccessor::operator=(std::move(other));
return * this; // return * this;
} //}
//
// Call the parent move ctor and also transfer own member. //// Call the parent move ctor and also transfer own member.
StorageAccessor::StorageAccessor(StorageAccessor&& other): //StorageAccessor::StorageAccessor(StorageAccessor&& other):
ConstStorageAccessor(std::move(other)), dataPointer(other.dataPointer) { // ConstStorageAccessor(std::move(other)), dataPointer(other.dataPointer) {
} //}
//
ConstStorageAccessor::ConstStorageAccessor(ConstStorageAccessor&& other): //ConstStorageAccessor::ConstStorageAccessor(ConstStorageAccessor&& other):
constDataPointer(other.constDataPointer), storeId(other.storeId), // constDataPointer(other.constDataPointer), storeId(other.storeId),
size_(other.size_), store(other.store), deleteData(other.deleteData), // size_(other.size_), store(other.store), deleteData(other.deleteData),
internalState(other.internalState) { // internalState(other.internalState) {
// Transfer ownership of the lock. // // Transfer ownership of the lock.
mutexLock = std::move(other.mutexLock); // mutexLock = std::move(other.mutexLock);
// This prevents double deletion of the resource. Not strictly necessary, // // This prevents double deletion of the resource. Not strictly necessary,
// from the testing I have conducted so far but I am not familiar enough // // from the testing I have conducted so far but I am not familiar enough
// with move semantics so I will just set the other lock to nullptr for now. // // with move semantics so I will just set the other lock to nullptr for now.
other.mutexLock = nullptr; // other.mutexLock = nullptr;
// This prevent premature deletion // // This prevent premature deletion
other.store = nullptr; // other.store = nullptr;
} //}
//
const uint8_t* ConstStorageAccessor::data() const { //const uint8_t* ConstStorageAccessor::data() const {
return constDataPointer; // return constDataPointer;
} //}
//
size_t ConstStorageAccessor::size() const { //size_t ConstStorageAccessor::size() const {
if(internalState == AccessState::UNINIT) { // if(internalState == AccessState::UNINIT) {
sif::warning << "StorageAccessor: Not initialized!" << std::endl; // sif::warning << "StorageAccessor: Not initialized!" << std::endl;
} // }
return size_; // return size_;
} //}
//
void ConstStorageAccessor::getDataCopy(uint8_t *pointer) { //void ConstStorageAccessor::getDataCopy(uint8_t *pointer) {
if(internalState == AccessState::UNINIT) { // if(internalState == AccessState::UNINIT) {
sif::warning << "StorageAccessor: Not initialized!" << std::endl; // sif::warning << "StorageAccessor: Not initialized!" << std::endl;
return; // return;
} // }
std::copy(constDataPointer, constDataPointer + size_, pointer); // std::copy(constDataPointer, constDataPointer + size_, pointer);
} //}
//
void ConstStorageAccessor::release() { //void ConstStorageAccessor::release() {
deleteData = false; // deleteData = false;
} //}
//
ReturnValue_t ConstStorageAccessor::lock(MutexIF* mutex, uint32_t mutexTimeout) { //ReturnValue_t ConstStorageAccessor::lock(MutexIF* mutex, uint32_t mutexTimeout) {
if(mutexLock == nullptr) { // if(mutexLock == nullptr) {
mutexLock = std::unique_ptr<MutexHelper>(new MutexHelper(mutex, mutexTimeout)); // mutexLock = std::unique_ptr<MutexHelper>(new MutexHelper(mutex, mutexTimeout));
return mutexLock.get()->getResult(); // return mutexLock.get()->getResult();
} // }
else { // else {
sif::warning << "StorageAccessor: Attempted to lock twice. Check code!" << std::endl; // sif::warning << "StorageAccessor: Attempted to lock twice. Check code!" << std::endl;
return HasReturnvaluesIF::RETURN_FAILED; // return HasReturnvaluesIF::RETURN_FAILED;
} // }
} //}
//
void ConstStorageAccessor::unlock() { //void ConstStorageAccessor::unlock() {
if(mutexLock != nullptr) { // if(mutexLock != nullptr) {
mutexLock.reset(); // mutexLock.reset();
} // }
} //}
//
store_address_t ConstStorageAccessor::getId() const { //store_address_t ConstStorageAccessor::getId() const {
return storeId; // return storeId;
} //}
//
void ConstStorageAccessor::print() const { //void ConstStorageAccessor::print() const {
if(internalState == AccessState::UNINIT) { // if(internalState == AccessState::UNINIT) {
sif::warning << "StorageAccessor: Not initialized!" << std::endl; // sif::warning << "StorageAccessor: Not initialized!" << std::endl;
return; // return;
} // }
sif::info << "StorageAccessor: Printing data: ["; // sif::info << "StorageAccessor: Printing data: [";
for(uint16_t iPool = 0; iPool < size_; iPool++) { // for(uint16_t iPool = 0; iPool < size_; iPool++) {
sif::info << std::hex << (int)constDataPointer[iPool]; // sif::info << std::hex << (int)constDataPointer[iPool];
if(iPool < size_ - 1){ // if(iPool < size_ - 1){
sif::info << " , "; // sif::info << " , ";
} // }
} // }
sif::info << " ] " << std::endl; // sif::info << " ] " << std::endl;
} //}
//
void ConstStorageAccessor::assignStore(StorageManagerIF* store) { //void ConstStorageAccessor::assignStore(StorageManagerIF* store) {
internalState = AccessState::READ; // internalState = AccessState::READ;
this->store = store; // this->store = store;
} //}
//
//
uint8_t* StorageAccessor::data() { //uint8_t* StorageAccessor::data() {
if(internalState == AccessState::UNINIT) { // if(internalState == AccessState::UNINIT) {
sif::warning << "StorageAccessor: Not initialized!" << std::endl; // sif::warning << "StorageAccessor: Not initialized!" << std::endl;
} // }
return dataPointer; // return dataPointer;
} //}
//
ReturnValue_t StorageAccessor::write(uint8_t *data, size_t size, //ReturnValue_t StorageAccessor::write(uint8_t *data, size_t size,
uint16_t offset) { // uint16_t offset) {
if(internalState == AccessState::UNINIT) { // if(internalState == AccessState::UNINIT) {
sif::warning << "StorageAccessor: Not initialized!" << std::endl; // sif::warning << "StorageAccessor: Not initialized!" << std::endl;
return HasReturnvaluesIF::RETURN_FAILED; // return HasReturnvaluesIF::RETURN_FAILED;
} // }
if(offset + size > size_) { // if(offset + size > size_) {
sif::error << "StorageAccessor: Data too large for pool entry!" << std::endl; // sif::error << "StorageAccessor: Data too large for pool entry!" << std::endl;
return HasReturnvaluesIF::RETURN_FAILED; // return HasReturnvaluesIF::RETURN_FAILED;
} // }
std::copy(data, data + size, dataPointer); // std::copy(data, data + size, dataPointer);
return HasReturnvaluesIF::RETURN_OK; // return HasReturnvaluesIF::RETURN_OK;
} //}
//
void StorageAccessor::assignConstPointer() { //void StorageAccessor::assignConstPointer() {
constDataPointer = dataPointer; // constDataPointer = dataPointer;
} //}
//
//

View File

@ -1,174 +1,174 @@
/** ///**
* @brief Helper classes to facilitate safe access to storages which is also // * @brief Helper classes to facilitate safe access to storages which is also
* conforming to RAII principles // * conforming to RAII principles
* @details These helper can be used together with the // * @details These helper can be used together with the
* StorageManager classes to manage access to a storage. // * StorageManager classes to manage access to a storage.
* It can take care of thread-safety while also providing // * It can take care of thread-safety while also providing
* mechanisms to automatically clear storage data and unlocking the // * mechanisms to automatically clear storage data and unlocking the
* pool. // * pool.
*/ // */
#ifndef TEST_PROTOTYPES_STORAGEACCESSOR_H_ //#ifndef TEST_PROTOTYPES_STORAGEACCESSOR_H_
#define TEST_PROTOTYPES_STORAGEACCESSOR_H_ //#define TEST_PROTOTYPES_STORAGEACCESSOR_H_
//
#include <framework/ipc/MutexHelper.h> //#include <framework/ipc/MutexHelper.h>
#include <framework/storagemanager/StorageManagerIF.h> //#include <framework/storagemanager/StorageManagerIF.h>
#include <memory> //#include <memory>
//
//
/** ///**
* @brief Accessor class which can be returned by pool managers // * @brief Accessor class which can be returned by pool managers
* or passed and set by pool managers to have safe access to the pool // * or passed and set by pool managers to have safe access to the pool
* resources. // * resources.
*/ // */
class ConstStorageAccessor { //class ConstStorageAccessor {
//! StorageManager classes have exclusive access to private variables. // //! StorageManager classes have exclusive access to private variables.
template<uint8_t NUMBER_OF_POOLS> // template<uint8_t NUMBER_OF_POOLS>
friend class PoolManager; // friend class PoolManager;
template<uint8_t NUMBER_OF_POOLS> // template<uint8_t NUMBER_OF_POOLS>
friend class LocalPool; // friend class LocalPool;
public: //public:
/** // /**
* @brief Simple constructor which takes the store ID of the storage // * @brief Simple constructor which takes the store ID of the storage
* entry to access. // * entry to access.
* @param storeId // * @param storeId
*/ // */
ConstStorageAccessor(store_address_t storeId); // ConstStorageAccessor(store_address_t storeId);
//
/** // /**
* @brief Move ctor and move assignment allow returning accessors as // * @brief Move ctor and move assignment allow returning accessors as
* a returnvalue. They prevent resource being free prematurely. // * a returnvalue. They prevent resource being free prematurely.
* Refer to: https://github.com/MicrosoftDocs/cpp-docs/blob/master/docs/cpp/ // * Refer to: https://github.com/MicrosoftDocs/cpp-docs/blob/master/docs/cpp/
* move-constructors-and-move-assignment-operators-cpp.md // * move-constructors-and-move-assignment-operators-cpp.md
* @param // * @param
* @return // * @return
*/ // */
ConstStorageAccessor& operator= (ConstStorageAccessor&&); // ConstStorageAccessor& operator= (ConstStorageAccessor&&);
ConstStorageAccessor (ConstStorageAccessor&&); // ConstStorageAccessor (ConstStorageAccessor&&);
//
//! The copy ctor and copy assignemnt should be deleted implicitely // //! The copy ctor and copy assignemnt should be deleted implicitely
//! according to https://foonathan.net/2019/02/special-member-functions/ // //! according to https://foonathan.net/2019/02/special-member-functions/
//! but I still deleted them to make it more explicit. (remember rule of 5). // //! but I still deleted them to make it more explicit. (remember rule of 5).
ConstStorageAccessor& operator= (ConstStorageAccessor&) = delete; // ConstStorageAccessor& operator= (ConstStorageAccessor&) = delete;
ConstStorageAccessor (ConstStorageAccessor&) = delete; // ConstStorageAccessor (ConstStorageAccessor&) = delete;
//
/** // /**
* @brief The destructor in default configuration takes care of // * @brief The destructor in default configuration takes care of
* deleting the accessed pool entry and unlocking the mutex // * deleting the accessed pool entry and unlocking the mutex
*/ // */
virtual ~ConstStorageAccessor(); // virtual ~ConstStorageAccessor();
//
/** // /**
* @brief Returns a pointer to the read-only data // * @brief Returns a pointer to the read-only data
* @return // * @return
*/ // */
const uint8_t* data() const; // const uint8_t* data() const;
//
/** // /**
* @brief Copies the read-only data to the supplied pointer // * @brief Copies the read-only data to the supplied pointer
* @param pointer // * @param pointer
*/ // */
void getDataCopy(uint8_t *pointer); // void getDataCopy(uint8_t *pointer);
//
/** // /**
* @brief Calling this will prevent the Accessor from deleting the data // * @brief Calling this will prevent the Accessor from deleting the data
* when the destructor is called. // * when the destructor is called.
*/ // */
void release(); // void release();
/** // /**
* @brief Locks the supplied mutex. // * @brief Locks the supplied mutex.
* @details // * @details
* The mutex will be unlocked automatically // * The mutex will be unlocked automatically
* when this class is destroyed (for example when exiting the scope). // * when this class is destroyed (for example when exiting the scope).
* Only one mutex can be locked at a time! // * Only one mutex can be locked at a time!
* @param mutex // * @param mutex
* @param mutexTimeout // * @param mutexTimeout
* @return // * @return
*/ // */
ReturnValue_t lock(MutexIF* mutex, // ReturnValue_t lock(MutexIF* mutex,
uint32_t mutexTimeout = MutexIF::NO_TIMEOUT); // uint32_t mutexTimeout = MutexIF::NO_TIMEOUT);
/** // /**
* @brief Unlocks the mutex (if one has been locked previously). // * @brief Unlocks the mutex (if one has been locked previously).
* Unless this function is called, the mutex is unlocked // * Unless this function is called, the mutex is unlocked
* when the class exits the scope. // * when the class exits the scope.
*/ // */
void unlock(); // void unlock();
//
//
/** // /**
* Get the size of the data // * Get the size of the data
* @return // * @return
*/ // */
size_t size() const; // size_t size() const;
//
/** // /**
* Get the storage ID. // * Get the storage ID.
* @return // * @return
*/ // */
store_address_t getId() const; // store_address_t getId() const;
//
void print() const; // void print() const;
protected: //protected:
const uint8_t* constDataPointer = nullptr; // const uint8_t* constDataPointer = nullptr;
store_address_t storeId; // store_address_t storeId;
size_t size_ = 0; // size_t size_ = 0;
//! Managing pool, has to assign itself. // //! Managing pool, has to assign itself.
StorageManagerIF* store = nullptr; // StorageManagerIF* store = nullptr;
//! Unique pointer to the mutex lock instance. Is initialized by // //! Unique pointer to the mutex lock instance. Is initialized by
//! the pool manager. // //! the pool manager.
std::unique_ptr<MutexHelper> mutexLock = nullptr; // std::unique_ptr<MutexHelper> mutexLock = nullptr;
bool deleteData = true; // bool deleteData = true;
//
enum class AccessState { // enum class AccessState {
UNINIT, // UNINIT,
READ // READ
}; // };
//! Internal state for safety reasons. // //! Internal state for safety reasons.
AccessState internalState = AccessState::UNINIT; // AccessState internalState = AccessState::UNINIT;
/** // /**
* Used by the pool manager instances to assign themselves to the // * Used by the pool manager instances to assign themselves to the
* accessor. This is necessary to delete the data when the acessor // * accessor. This is necessary to delete the data when the acessor
* exits the scope ! The internal state will be considered read // * exits the scope ! The internal state will be considered read
* when this function is called, so take care all data is set properly as // * when this function is called, so take care all data is set properly as
* well. // * well.
* @param // * @param
*/ // */
void assignStore(StorageManagerIF*); // void assignStore(StorageManagerIF*);
//
}; //};
//
//
/** ///**
* @brief Child class for modifyable data. Also has a normal pointer member. // * @brief Child class for modifyable data. Also has a normal pointer member.
*/ // */
class StorageAccessor: public ConstStorageAccessor { //class StorageAccessor: public ConstStorageAccessor {
//! StorageManager classes have exclusive access to private variables. // //! StorageManager classes have exclusive access to private variables.
template<uint8_t NUMBER_OF_POOLS> // template<uint8_t NUMBER_OF_POOLS>
friend class PoolManager; // friend class PoolManager;
template<uint8_t NUMBER_OF_POOLS> // template<uint8_t NUMBER_OF_POOLS>
friend class LocalPool; // friend class LocalPool;
public: //public:
StorageAccessor(store_address_t storeId); // StorageAccessor(store_address_t storeId);
/** // /**
* @brief Move ctor and move assignment allow returning accessors as // * @brief Move ctor and move assignment allow returning accessors as
* a returnvalue. They prevent resource being free prematurely. // * a returnvalue. They prevent resource being free prematurely.
* Refer to: https://github.com/MicrosoftDocs/cpp-docs/blob/master/docs/cpp/ // * Refer to: https://github.com/MicrosoftDocs/cpp-docs/blob/master/docs/cpp/
* move-constructors-and-move-assignment-operators-cpp.md // * move-constructors-and-move-assignment-operators-cpp.md
* @param // * @param
* @return // * @return
*/ // */
StorageAccessor& operator= (StorageAccessor&&); // StorageAccessor& operator= (StorageAccessor&&);
StorageAccessor (StorageAccessor&&); // StorageAccessor (StorageAccessor&&);
//
ReturnValue_t write(uint8_t *data, size_t size, // ReturnValue_t write(uint8_t *data, size_t size,
uint16_t offset); // uint16_t offset);
uint8_t* data(); // uint8_t* data();
//
private: //private:
//! Non-const pointer for modifyable data. // //! Non-const pointer for modifyable data.
uint8_t* dataPointer = nullptr; // uint8_t* dataPointer = nullptr;
//! For modifyable data, the const pointer is assigned to the normal // //! For modifyable data, the const pointer is assigned to the normal
//! pointer by the pool manager so both access functions can be used safely // //! pointer by the pool manager so both access functions can be used safely
void assignConstPointer(); // void assignConstPointer();
}; //};
//
#endif /* TEST_PROTOTYPES_STORAGEACCESSOR_H_ */ //#endif /* TEST_PROTOTYPES_STORAGEACCESSOR_H_ */