AuroraRuntime/Include/Aurora/Threading/LockGuard.hpp

86 lines
2.4 KiB
C++
Raw Normal View History

2021-06-27 21:25:29 +00:00
/***
Copyright (C) 2021 J Reece Wilson (a/k/a "Reece"). All rights reserved.
File: LockGuard.hpp
Date: 2021-6-10
Author: Reece
***/
#pragma once
namespace Aurora::Threading
{
2023-03-22 22:07:00 +00:00
template <class T>
struct AuOperatorArrow
{
template <class C> static constexpr AuTrueType Test(decltype(&C::operator->));
template <class C> static constexpr AuFalseType Test(...);
using type = decltype(Test<const T>(0));
};
2021-06-27 21:25:29 +00:00
template<typename T>
class LockGuard
{
2023-03-22 22:07:00 +00:00
using Constless_t = T;
using ConstlessPtr_t = AuConditional_t<AuIsPointer_v<Constless_t>, Constless_t, Constless_t *>;
using Internal_t = AuRemovePointer_t<Constless_t>;
static const bool kBoolArrowOp = AuOperatorArrow<AuRemovePointer_t<T>>::type::value;
2021-09-06 10:58:08 +00:00
2021-06-27 21:25:29 +00:00
public:
2021-09-06 10:58:08 +00:00
auline LockGuard(const T &lock)
2021-09-06 10:58:08 +00:00
{
2023-03-22 22:07:00 +00:00
ConstlessPtr_t pInterface {};
2022-01-19 17:08:13 +00:00
if constexpr (AuIsPointer_v<T>)
2021-09-06 10:58:08 +00:00
{
2023-03-22 22:07:00 +00:00
pInterface = (ConstlessPtr_t)lock;
2021-09-06 10:58:08 +00:00
}
else
{
2023-03-22 22:07:00 +00:00
pInterface = (ConstlessPtr_t)&lock;
2021-09-06 10:58:08 +00:00
}
if constexpr (AuIsBaseOfTemplate<AURORA_RUNTIME_AU_SHARED_PTR, Internal_t>::value || AuIsBaseOfTemplate<AURORA_RUNTIME_AU_UNIQUE_PTR, Internal_t>::value)
{
2023-03-22 22:07:00 +00:00
pInterface->get()->Lock();
2021-09-06 10:58:08 +00:00
}
2023-03-22 22:07:00 +00:00
else if constexpr (kBoolArrowOp)
2021-09-06 10:58:08 +00:00
{
2023-03-22 22:07:00 +00:00
(*pInterface)->Lock();
2021-09-06 10:58:08 +00:00
}
else
{
2023-03-22 22:07:00 +00:00
pInterface->Lock();
2021-09-06 10:58:08 +00:00
}
2023-03-22 22:07:00 +00:00
this->pAnnoying_ = pInterface;
2021-06-27 21:25:29 +00:00
}
auline ~LockGuard()
2021-06-27 21:25:29 +00:00
{
2023-03-22 22:07:00 +00:00
if (!this->pAnnoying_)
2022-01-21 19:36:56 +00:00
{
return;
}
2021-09-06 10:58:08 +00:00
if constexpr (AuIsBaseOfTemplate<AURORA_RUNTIME_AU_SHARED_PTR, Internal_t>::value || AuIsBaseOfTemplate<AURORA_RUNTIME_AU_UNIQUE_PTR, Internal_t>::value)
{
2023-03-22 22:07:00 +00:00
this->pAnnoying_->get()->Unlock();
}
else if constexpr (kBoolArrowOp)
{
(*this->pAnnoying_)->Unlock();
2021-09-06 10:58:08 +00:00
}
else
{
2023-03-22 22:07:00 +00:00
this->pAnnoying_->Unlock();
2021-09-06 10:58:08 +00:00
}
2021-06-27 21:25:29 +00:00
}
private:
2023-03-22 22:07:00 +00:00
ConstlessPtr_t pAnnoying_ {};
2021-06-27 21:25:29 +00:00
};
2021-09-06 10:58:08 +00:00
#define AU_LOCK_GUARD(variable) Aurora::Threading::LockGuard<decltype(variable)> AU_CONCAT(__stack_lock, __COUNTER__) (variable);
2021-06-27 21:25:29 +00:00
}