105 lines
2.1 KiB
C++
105 lines
2.1 KiB
C++
/***
|
|
Copyright (C) 2021 J Reece Wilson (a/k/a "Reece"). All rights reserved.
|
|
|
|
File: RWLock.hpp
|
|
Date: 2021-6-12
|
|
Author: Reece
|
|
***/
|
|
#pragma once
|
|
|
|
namespace Aurora::Threading::Primitives
|
|
{
|
|
class RWLockImpl;
|
|
|
|
template<bool isread>
|
|
class RWLockAccessView : public IWaitable
|
|
{
|
|
public:
|
|
RWLockAccessView(RWLockImpl &impl) : parent_(impl)
|
|
{
|
|
|
|
}
|
|
|
|
bool Lock(AuUInt64 timeout) override
|
|
{
|
|
if constexpr (isread)
|
|
{
|
|
return parent_.LockRead(timeout);
|
|
}
|
|
else
|
|
{
|
|
return parent_.LockWrite(timeout);
|
|
}
|
|
}
|
|
|
|
bool TryLock() override
|
|
{
|
|
if constexpr (isread)
|
|
{
|
|
return parent_.TryLockRead();
|
|
}
|
|
else
|
|
{
|
|
return parent_.TryLockWrite();
|
|
}
|
|
}
|
|
|
|
bool HasOSHandle(AuMach &mach) override
|
|
{
|
|
return false;
|
|
}
|
|
|
|
bool HasLockImplementation() override
|
|
{
|
|
return true;
|
|
}
|
|
|
|
void Lock() override
|
|
{
|
|
SysAssert(Lock(0));
|
|
}
|
|
|
|
void Unlock() override
|
|
{
|
|
if constexpr (isread)
|
|
{
|
|
parent_.UnlockRead();
|
|
}
|
|
else
|
|
{
|
|
parent_.UnlockWrite();
|
|
}
|
|
}
|
|
|
|
private:
|
|
RWLockImpl &parent_;
|
|
};
|
|
|
|
class RWLockImpl : public RWLock
|
|
{
|
|
public:
|
|
RWLockImpl();
|
|
~RWLockImpl();
|
|
|
|
bool LockRead(AuUInt64 timeout);
|
|
bool LockWrite(AuUInt64 timeout);
|
|
bool TryLockRead();
|
|
bool TryLockWrite();
|
|
void UnlockRead();
|
|
void UnlockWrite();
|
|
|
|
IWaitable *AsReadable() override;
|
|
IWaitable *AsWritable() override;
|
|
|
|
bool Init();
|
|
|
|
private:
|
|
|
|
RWLockAccessView<true> read_;
|
|
RWLockAccessView<false> write_;
|
|
|
|
ConditionMutexUnique_t mutex_;
|
|
ConditionVariableUnique_t condition_;
|
|
std::atomic<int> state_;
|
|
};
|
|
} |