Sometimes you need access, to classes/objects/structs from different threads.
This is a template which wraps a object, and protected it against direct access. If you want to modify the object you have to create a copy of it.
Also this template has handy methods like compareAndSet/swap, which helps you to change data in a consistent way, without locking it during the change process.
I’m not saying this is very CPU/Memory efficient, but it should be safe by design.
What do you think? (How can it be improved/optimized?)
Example (Pseudo-Code)
ThreadSafeObject<MyData> data;
void runThread()
{
while(false)
{
MyData localcopy(data.get());
MyData copyToCompare(localcopy);
localCopy.applySomeChanges();
data.compareAndSetBool(localCopy,copyToCompare);
}
}
// Thread Safe Object Wrapper
// The object itself is protected against direct access, its only possible to get a copy
// Only Objects&Classes are supported, which have a assignment operator and a copy constructor
template <class ObjectType>
class ThreadSafeObject
{
public:
inline ThreadSafeObject (ObjectType _object) noexcept
: object (_object)
{
}
ObjectType get() noexcept
{
ScopedLock sl(cs);
return object;
}
void set(const ObjectType& _object) noexcept
{
ScopedLock sl(cs);
object=_object;
}
bool compareAndSetBool (const ObjectType& newValue, const ObjectType& valueToCompare) noexcept
{
ScopedLock sl(cs);
if (object == valueToCompare)
{
object = newValue;
return true;
}
return false;
}
ObjectType compareAndSetValue (const ObjectType& newValue, const ObjectType& valueToCompare) noexcept
{
ScopedLock sl(cs);
ObjectType oldValue = object;
if (oldValue == valueToCompare)
object = oldValue;
return oldValue;
}
void swap (const ThreadSafeObject& other) noexcept
{
ScopedLock sl1(cs);
ScopedLock sl2(other.cs);
ObjectType old = object;
object = other.object;
other.object = old;
}
private:
CriticalSection cs;
ObjectType object;
};