The Data Access Layer is the only object that interfaces directly with the Data Store.
It ensures thread-safety via Data Element Accessors (class: EcDataElementAccessor
)
The Data Access Layer provides methods for getting and setting element data by
uniqueLockHandle()
and sharedLockHandle()
methodsAn accessor provides safe access to the data store to read and write data values including primitive (int, double, float, string) as well as objects and resource references.
// check that the accessor is valid and compare the value with the provided value
if(accessor)
{
EcBoolean retVal = EcTrue;
ValueType valueCopy = value;
// accessors provide direct thread safe access through four methods
// * accessor->setValue
// * accessor->getValue
// * accessor->sharedLockHandle
// * accessor->uniqueLockHandle
// The setValue and getValue methods perform implicit mutex locking
// The sharedLockHandle and uniqueLockHandle perform explicit mutex locking
// we will now test all access methods
// Try using a shared handle for read only access
// A shared lock is obtained when the handle is created and released when it is destroyed.
{
EcSharedLockDataHandle<ValueType> handle = accessor->sharedLockHandle();
const ValueType& valueConstRef = handle.value();
retVal &= (valueConstRef == value);
}
// Next try using a unique handle for read/write access
// A unique lock is obtained when the handle is created and released when it is destroyed.
{
EcUniqueLockDataHandle<ValueType> handle = accessor->uniqueLockHandle();
ValueType& valueRef = handle.value();
retVal &= (valueRef == value);
}
// setValue returns true if the value is set.
// A unique lock is obtained implicitly while the copy operation is performed.
retVal &= accessor->setValue(valueCopy);
// getValue returns true if the value is retrieved.
// A shared lock is obtained implicitly while the copy operation is performed
retVal &= accessor->getValue(valueCopy);
// check the retrieved value
retVal &= (valueCopy == value);
return retVal;
}
Source code: examples/dataStoreConfigExample/ecDataStoreConfigExample.h
The code snapshot in figure 1 shows how to lock the resource for either reading or writing, and then how to set or get the element of interest.
Accessing groups of data elements can be done through the EcDataGroupAccessor
class. This reduces the possibility of deadlocks by locking elements in the same order.
A group lock is constructed from a tuple of EcDataElementAccessor
typename EcDataGroupAccessor<AccessorTuple>::shared_ptr pGroupAccessor( new EcDataGroupAccessor<AccessorTuple>(accessorTuple));
if(!pGroupAccessor->isValid())
{
return EcFalse;
}
// First try using a shared lock group handle for read/write access
// The group's mutexes are locked in order based on address of the mutex and unlocked in the reverse order.
EcBoolean retVal = EcTrue;
EcPrint(Info) << " --Group Shared Lock Test:" << std::endl;
{
EcSharedLockGroupHandle<AccessorTuple> handle = pGroupAccessor->sharedLockHandle();
// Use the test helper to iterate through all the tuple elements and
// check if the accessed value is equal to the test value
retVal &= EcDataGroupTestHelper<
EcSharedLockGroupHandle<AccessorTuple>,
ValueTuple,
ecboost::tuples::length<ValueTuple>::value
>::test
(
handle,
valueTuple
);
}
EcPrint(Info) << " --Group Unique Lock Test:" << std::endl;
// Next try using a unique handle for read/write access
// The group's mutexes are locked in order based on address of the mutex and unlocked in the reverse order.
{
EcUniqueLockGroupHandle<AccessorTuple> handle = pGroupAccessor->uniqueLockHandle();
// Use the test helper to iterate through all the tuple elements and
// check if the accessed value is equal to the test value
retVal &= EcDataGroupTestHelper<
EcUniqueLockGroupHandle<AccessorTuple>,
ValueTuple,
ecboost::tuples::length<ValueTuple>::value
>::test
(
handle,
valueTuple
);
}
Source code: examples/dataStoreConfigExample/ecDataStoreConfigExample.h
EcDataAccessLayer m_DataAccessLayer;
...
m_DataAccessLayer.addDataElement(COUNT, EcU32(0) );