[+] AuCompression::CompressionInterceptor

[+] AuCrypto::CBC::CBCContext
[+] AuFS::ReadDirRecursive
[+] AuFS::DirDeleter
[+] AuCrypto::PBKDF2
[+] AuCrypto::AES::CBCEncrypt
[+] AuCrypto::AES::CBCDecrypt
[+] AuCrypto::TDES::CBCEncrypt
[+] AuCrypto::TDES::CBCDecrypt
[+] Optimize read write locks
[*] Added `ContextFlags = CONTEXT_ALL` to Win32 PlatformWalkCallStack
This commit is contained in:
Reece Wilson 2022-11-06 12:30:06 +00:00
parent 48a8e4ae5a
commit d63571e4b5
25 changed files with 940 additions and 13 deletions

View File

@ -22,6 +22,8 @@
// Utility
#include "BasicCompression.hpp"
#include "CompressionInterceptor.hpp"
// TODO: neat comment + real world data

View File

@ -0,0 +1,21 @@
/***
Copyright (C) 2022 J Reece Wilson (a/k/a "Reece"). All rights reserved.
File: CompressionInterceptor.hpp
Date: 2022-9-14
Author: Reece
***/
#pragma once
#include <Aurora/IO/Protocol/IProtocolInterceptorEx.hpp>
namespace Aurora::Compression
{
struct ICompressionInterceptor : IO::Protocol::IProtocolInterceptorEx
{
virtual bool HasFailed() = 0;
};
AUKN_SYM AuSPtr<ICompressionInterceptor> NewDecompressionInterceptor(const DecompressInfo &info);
AUKN_SYM AuSPtr<ICompressionInterceptor> NewCompressionInterceptor(const CompressInfo &info);
}

View File

@ -9,6 +9,29 @@
namespace Aurora::Crypto::AES
{
/**
* @brief
* @param pContext
* @param memoryView
* @return
*/
AUKN_SYM bool CBCEncrypt(const AuSPtr<CBC::ICBCContext> pContext,
const Memory::MemoryViewWrite &memoryView);
/**
* @brief
* @param pContext
* @param memoryView
* @return
*/
AUKN_SYM bool CBCDecrypt(const AuSPtr<CBC::ICBCContext> pContext,
const Memory::MemoryViewWrite &memoryView);
/**
* @brief
* @param plainText
* @return
*/
AUKN_SYM AuUInt GetSafeCipherPadding(const Memory::MemoryViewRead &plainText);
// Remember: AES works in chunks of 128 bits

View File

@ -0,0 +1,23 @@
/***
Copyright (C) 2022 J Reece Wilson (a/k/a "Reece"). All rights reserved.
File: CBC.hpp
Date: 2022-10-08
Author: Reece
***/
#pragma once
namespace Aurora::Crypto::CBC
{
struct ICBCContext
{
virtual bool Initialize(const Memory::MemoryViewRead &key,
const Memory::MemoryViewRead &iv) = 0;
virtual bool GetIV(const Memory::MemoryViewWrite &writeView) = 0;
virtual bool SetIV(const Memory::MemoryViewRead &readView) = 0;
};
AUKN_SHARED_API(NewContext, ICBCContext);
}

View File

@ -28,8 +28,13 @@ namespace Aurora::Crypto
#else
#include <Aurora/Hashing/EHashType.hpp>
#endif
#include "EKeyType.hpp"
#include "EPaddingType.hpp"
#include "CBC/CBC.hpp"
#include "TDES/TDES.hpp"
#include "PBKDF2/PBKDF2.hpp"
#include "AES/AES.hpp"
#include "X509/X509.hpp"
#include "CA/CA.hpp"

View File

@ -0,0 +1,17 @@
/***
Copyright (C) 2022 J Reece Wilson (a/k/a "Reece"). All rights reserved.
File: PBKDF2.hpp
Date: 2022-10-08
Author: Reece
***/
#pragma once
namespace Aurora::Crypto::PBKDF2
{
AUKN_SYM bool PBKDF2(const Memory::MemoryViewRead &salt,
const Memory::MemoryViewRead &password,
Hashing::EHashType hashType,
AuUInt32 uIterations,
const Memory::MemoryViewWrite &out);
}

View File

@ -0,0 +1,29 @@
/***
Copyright (C) 2022 J Reece Wilson (a/k/a "Reece"). All rights reserved.
File: TDES.hpp
Date: 2022-10-08
Author: Reece
***/
#pragma once
namespace Aurora::Crypto::TDES
{
/**
* @brief
* @param pContext
* @param memoryView
* @return
*/
AUKN_SYM bool CBCEncrypt(const AuSPtr<CBC::ICBCContext> pContext,
const Memory::MemoryViewWrite &memoryView);
/**
* @brief
* @param pContext
* @param memoryView
* @return
*/
AUKN_SYM bool CBCDecrypt(const AuSPtr<CBC::ICBCContext> pContext,
const Memory::MemoryViewWrite &memoryView);
}

View File

@ -30,6 +30,20 @@ namespace Aurora::IO::FS
*/
AUKN_SYM AuSPtr<IReadDir> ReadDir(const AuString &directory);
/**
* @brief
* @param string
* @return
*/
AUKN_SYM AuSPtr<IReadDir> ReadDirRecursive(const AuString &string);
/**
* @brief Recursively deletes any given path
* @param string
* @return
*/
AUKN_SYM bool DirDeleter(const AuString &string);
/**
* @brief Writes a blob into a file chunk-by-chunk.
* The directory structure may or may not exist for the write operation to succeed.

View File

@ -37,6 +37,7 @@ namespace Crypto
gHashRMD320 = register_hash(&rmd320_desc);
gPrngYarrow = register_prng(&yarrow_desc);
gAesCipher = register_cipher(&aes_desc);
gDesCipher = register_cipher(&des3_desc);
}
static void MBedTlsInit()

View File

@ -10,6 +10,7 @@
namespace Crypto
{
inline int gAesCipher;
inline int gDesCipher;
inline int gHashTiger;
inline int gHashSha1;
inline int gHashMD4;

View File

@ -0,0 +1,126 @@
/***
Copyright (C) 2022 J Reece Wilson (a/k/a "Reece"). All rights reserved.
File: CompressionInterceptor.cpp
Date: 2022-9-14
Author: Reece
***/
#include <Source/RuntimeInternal.hpp>
#include "Compression.hpp"
#include "BaseStream.hpp"
#include "CompressionInterceptor.hpp"
namespace Aurora::Compression
{
CompressionInterceptor::CompressionInterceptor()
{
}
void CompressionInterceptor::Init(const AuSPtr<ICompressionStream> &pStream,
const AuSPtr<BaseStream> &pBaseStream)
{
this->pBaseStream_ = pBaseStream;
this->pStream_ = pStream;
}
IO::EStreamError CompressionInterceptor::IsOpen()
{
return IO::EStreamError::eErrorNone;
}
IO::EStreamError CompressionInterceptor::Read(const Memory::MemoryViewStreamWrite &parameters)
{
if (auto pBuffer = this->pLastBuffer_.lock())
{
parameters.outVariable = pBuffer->Read(parameters.ptr, parameters.length);
return parameters.outVariable == 0 ? IO::EStreamError::eErrorEndOfStream : IO::EStreamError::eErrorNone;
}
return IO::EStreamError::eErrorStreamNotOpen;
}
void CompressionInterceptor::Close()
{
}
bool CompressionInterceptor::HasFailed()
{
return this->bErrorFlag_;
}
bool CompressionInterceptor::OnDataAvailable(const AuSPtr<Memory::ByteBuffer> &pReadInByteBuffer,
const AuSPtr<Memory::ByteBuffer> &pWriteOutByteBuffer)
{
this->pLastBuffer_ = pReadInByteBuffer;
this->pBaseStream_->SetBuffer(pWriteOutByteBuffer);
bool bSuccess { true };
do
{
auto uReadable = pReadInByteBuffer->GetNextLinearRead();
if (!uReadable)
{
break;
}
auto [a, b] = this->pBaseStream_->Ingest(uReadable);
bSuccess = a != 0;
}
while (bSuccess);
if (!bSuccess)
{
this->bErrorFlag_ = true;
}
this->pBaseStream_->SetBuffer({});
return true;
}
AUKN_SYM AuSPtr<ICompressionInterceptor> NewDecompressionInterceptor(const DecompressInfo &info)
{
auto pInterceptor = AuMakeShared<CompressionInterceptor>();
if (!pInterceptor)
{
SysPushErrorMemory();
return {};
}
auto pDecompressor = DecompressorShared(AuUnsafeRaiiToShared(pInterceptor.get()),
info);
if (!pDecompressor)
{
SysPushErrorMemory();
return {};
}
pInterceptor->Init(pDecompressor,
AuStaticCast<Compression::BaseStream>(pDecompressor));
return pInterceptor;
}
AUKN_SYM AuSPtr<ICompressionInterceptor> NewCompressionInterceptor(const CompressInfo &info)
{
auto pInterceptor = AuMakeShared<CompressionInterceptor>();
if (!pInterceptor)
{
SysPushErrorMemory();
return {};
}
auto pCompressor = CompressorShared(AuUnsafeRaiiToShared(pInterceptor.get()),
info);
if (!pCompressor)
{
SysPushErrorMemory();
return {};
}
pInterceptor->Init(pCompressor,
AuStaticCast<Compression::BaseStream>(pCompressor));
return pInterceptor;
}
}

View File

@ -0,0 +1,38 @@
/***
Copyright (C) 2022 J Reece Wilson (a/k/a "Reece"). All rights reserved.
File: CompressionInterceptor.hpp
Date: 2022-9-14
Author: Reece
***/
#pragma once
#include <IO/Protocol/Protocol.hpp>
namespace Aurora::Compression
{
struct CompressionInterceptor : ICompressionInterceptor, IO::IStreamReader
{
CompressionInterceptor();
void Init(const AuSPtr<ICompressionStream> &pStream,
const AuSPtr<BaseStream> &pBaseStream);
bool OnDataAvailable(const AuSPtr<Memory::ByteBuffer> &pReadInByteBuffer,
const AuSPtr<Memory::ByteBuffer> &pWriteOutByteBuffer) override;
inline virtual IO::EStreamError IsOpen() override;
inline virtual IO::EStreamError Read(const Memory::MemoryViewStreamWrite &parameters) override;
inline virtual void Close() override;
bool HasFailed() override;
private:
bool bErrorFlag_ {};
AuSPtr<ICompressionStream> pStream_;
AuSPtr<BaseStream> pBaseStream_;
AuWPtr<Memory::ByteBuffer> pLastBuffer_;
};
}

View File

@ -10,9 +10,48 @@
#include "Aes.hpp"
#include <tomcrypt.h>
#include <Source/AuCrypto.hpp>
#include "../CBC/CBC.hpp"
namespace Aurora::Crypto::AES
{
AUKN_SYM bool CBCEncrypt(const AuSPtr<CBC::ICBCContext> pContext,
const Memory::MemoryViewWrite &memoryView)
{
if (!pContext)
{
SysPushErrorArg();
return false;
}
if (!memoryView.ptr)
{
SysPushErrorArg();
return false;
}
return AuStaticCast<CBC::CBCContext>(pContext)->Encrypt(::Crypto::gAesCipher,
memoryView);
}
AUKN_SYM bool CBCDecrypt(const AuSPtr<CBC::ICBCContext> pContext,
const Memory::MemoryViewWrite &memoryView)
{
if (!pContext)
{
SysPushErrorArg();
return false;
}
if (!memoryView.ptr)
{
SysPushErrorArg();
return false;
}
return AuStaticCast<CBC::CBCContext>(pContext)->Decrypt(::Crypto::gAesCipher,
memoryView);
}
AUKN_SYM AuUInt GetSafeCipherPadding(const Memory::MemoryViewRead &parameters)
{
auto tptr = reinterpret_cast<const unsigned char *>(parameters.ptr);

165
Source/Crypto/CBC/CBC.cpp Normal file
View File

@ -0,0 +1,165 @@
/***
Copyright (C) 2022 J Reece Wilson (a/k/a "Reece"). All rights reserved.
File: CBC.cpp
Date: 2022-10-08
Author: Reece
***/
#include <Source/RuntimeInternal.hpp>
#include "../Crypto.hpp"
#include "CBC.hpp"
namespace Aurora::Crypto::CBC
{
bool CBCContext::Initialize(const Memory::MemoryViewRead &key,
const Memory::MemoryViewRead &iv)
{
if (iv.length > 32)
{
SysPushErrorArg();
return false;
}
if (!iv.ptr)
{
SysPushErrorArg();
return false;
}
if (!key.ptr)
{
SysPushErrorArg();
return false;
}
if (key.length > AuArraySize(this->streamKey_))
{
SysPushErrorArg();
return false;
}
AuMemcpy(this->cbc_.IV, iv.ptr, iv.length);
this->iIVLength = iv.length;
this->iKeyLength = key.length;
AuMemcpy(this->streamKey_, key.ptr, key.length);
return true;
}
bool CBCContext::GetIV(const Memory::MemoryViewWrite &writeView)
{
if (!writeView.ptr)
{
SysPushErrorArg();
return false;
}
if (writeView.length != this->cbc_.blocklen)
{
return {};
}
AuMemcpy(writeView.ptr, this->cbc_.IV, this->cbc_.blocklen);
return true;
}
bool CBCContext::SetIV(const Memory::MemoryViewRead &readView)
{
if (!readView.ptr)
{
SysPushErrorArg();
return false;
}
if (readView.length != this->cbc_.blocklen)
{
return {};
}
AuMemcpy(this->cbc_.IV, readView.ptr, this->cbc_.blocklen);
return true;
}
bool CBCContext::TryInit(int iCipher)
{
char iv[32];
int iRet {};
if (this->iLastCipher_ != -1)
{
return this->iLastCipher_ == iCipher;
}
AuMemcpy(iv, this->cbc_.IV, 32);
iRet = ::cbc_start(iCipher,
AuReinterpretCast<const unsigned char *>(iv),
AuReinterpretCast<const unsigned char *>(this->streamKey_),
this->iKeyLength,
0,
&this->cbc_);
if (iRet != CRYPT_OK)
{
SysPushErrorCrypt("{}", iRet);
return {};
}
this->iLastCipher_ = iCipher;
return true;
}
bool CBCContext::Decrypt(int iCipher,
const Memory::MemoryViewWrite &memoryView)
{
int iRet {};
if (!TryInit(iCipher))
{
return false;
}
iRet = ::cbc_decrypt(AuReinterpretCast<const unsigned char *>(memoryView.ptr),
AuReinterpretCast<unsigned char *>(memoryView.ptr),
memoryView.length,
&this->cbc_);
if (iRet != CRYPT_OK)
{
SysPushErrorCrypt("{}", iRet);
return false;
}
return true;
}
bool CBCContext::Encrypt(int iCipher,
const Memory::MemoryViewWrite &memoryView)
{
int iRet {};
if (!TryInit(iCipher))
{
return false;
}
iRet = ::cbc_encrypt(AuReinterpretCast<const unsigned char *>(memoryView.ptr),
AuReinterpretCast<unsigned char *>(memoryView.ptr),
memoryView.length,
&this->cbc_);
if (iRet != CRYPT_OK)
{
SysPushErrorCrypt("{}", iRet);
return false;
}
return true;
}
AUKN_SYM ICBCContext *NewContextNew()
{
return _new CBCContext();
}
AUKN_SYM void NewContextRelease(ICBCContext *pContext)
{
AuSafeDelete<CBCContext *>(pContext);
}
}

31
Source/Crypto/CBC/CBC.hpp Normal file
View File

@ -0,0 +1,31 @@
/***
Copyright (C) 2022 J Reece Wilson (a/k/a "Reece"). All rights reserved.
File: CBC.hpp
Date: 2022-10-08
Author: Reece
***/
#pragma once
namespace Aurora::Crypto::CBC
{
struct CBCContext : ICBCContext
{
bool Initialize(const Memory::MemoryViewRead &key,
const Memory::MemoryViewRead &iv) override;
bool GetIV(const Memory::MemoryViewWrite &writeView) override;
bool SetIV(const Memory::MemoryViewRead &readView) override;
bool TryInit(int iCipher);
bool Decrypt(int iCipher, const Memory::MemoryViewWrite &memoryView);
bool Encrypt(int iCipher, const Memory::MemoryViewWrite &memoryView);
private:
symmetric_CBC cbc_ {};
char streamKey_[32];
int iKeyLength {};
int iIVLength {};
int iLastCipher_ { -1 };
};
}

View File

@ -0,0 +1,29 @@
/***
Copyright (C) 2022 J Reece Wilson (a/k/a "Reece"). All rights reserved.
File: PBKDF2.cpp
Date: 2022-10-08
Author: Reece
***/
#include <Source/RuntimeInternal.hpp>
#include "../Crypto.hpp"
namespace Aurora::Crypto::PBKDF2
{
AUKN_SYM bool PBKDF2(const Memory::MemoryViewRead &salt,
const Memory::MemoryViewRead &password,
Hashing::EHashType hashType,
AuUInt32 uIterations,
const Memory::MemoryViewWrite &out)
{
unsigned long len = out.length;
return ::pkcs_5_alg2(password.Begin<unsigned char>(),
password.length,
salt.Begin<unsigned char>(),
salt.length,
uIterations,
::Crypto::HashMethodToId(hashType),
out.Begin<unsigned char>(),
&len) == CRYPT_OK && len == out.length;
}
}

View File

@ -0,0 +1,9 @@
/***
Copyright (C) 2022 J Reece Wilson (a/k/a "Reece"). All rights reserved.
File: PBKDF2.hpp
Date: 2022-10-08
Author: Reece
***/
#pragma once

View File

@ -0,0 +1,52 @@
/***
Copyright (C) 2022 J Reece Wilson (a/k/a "Reece"). All rights reserved.
File: TDES.cpp
Date: 2022-10-08
Author: Reece
***/
#include <Source/RuntimeInternal.hpp>
#include "../Crypto.hpp"
#include "TDES.hpp"
#include "../CBC/CBC.hpp"
namespace Aurora::Crypto::TDES
{
AUKN_SYM bool CBCEncrypt(const AuSPtr<CBC::ICBCContext> pContext,
const Memory::MemoryViewWrite &memoryView)
{
if (!pContext)
{
SysPushErrorArg();
return false;
}
if (!memoryView.ptr)
{
SysPushErrorArg();
return false;
}
return AuStaticCast<CBC::CBCContext>(pContext)->Encrypt(::Crypto::gDesCipher,
memoryView);
}
AUKN_SYM bool CBCDecrypt(const AuSPtr<CBC::ICBCContext> pContext,
const Memory::MemoryViewWrite &memoryView)
{
if (!pContext)
{
SysPushErrorArg();
return false;
}
if (!memoryView.ptr)
{
SysPushErrorArg();
return false;
}
return AuStaticCast<CBC::CBCContext>(pContext)->Decrypt(::Crypto::gDesCipher,
memoryView);
}
}

View File

@ -0,0 +1,9 @@
/***
Copyright (C) 2022 J Reece Wilson (a/k/a "Reece"). All rights reserved.
File: TDES.hpp
Date: 2022-10-08
Author: Reece
***/
#pragma once

View File

@ -122,8 +122,13 @@ namespace Aurora::Debug
StackTrace PlatformWalkCallStack()
{
StackTrace ret;
CONTEXT ctx;
if (!GetThreadContext(GetCurrentThread(), &ctx)) return {};
CONTEXT ctx {};
ctx.ContextFlags = CONTEXT_ALL;
if (!GetThreadContext(GetCurrentThread(), &ctx))
{
return {};
}
ParseStack(&ctx, ret);
return ret;
}

121
Source/IO/FS/DirDeleter.cpp Normal file
View File

@ -0,0 +1,121 @@
/***
Copyright (C) 2022 J Reece Wilson (a/k/a "Reece"). All rights reserved.
File: DirDeleter.cpp
Date: 2022-11-06
Author: Reece
***/
#include <Source/RuntimeInternal.hpp>
#include "FS.hpp"
namespace Aurora::IO::FS
{
struct RecursiveDirDeleter : IReadDir
{
AuSPtr<IReadDir> pDir;
AuList<AuString> nextLevel;
AuList<AuString> nextLevel2;
AuString curPath;
AuString curSubDir;
bool OpenDir(const AuString &str)
{
curPath = str;
pDir = ReadDir(str);
return bool(pDir);
}
bool OpenNext(const AuString &str)
{
curPath = str;
pDir = ReadDir(str);
return bool(pDir);
}
void DoNext()
{
this->pDir.reset();
if (!nextLevel.size())
{
return;
}
auto a = nextLevel[0];
nextLevel.erase(nextLevel.begin());
this->pDir = ReadDir(curPath + "/" + a);
curSubDir = a;
}
virtual StatEx *Next() override
{
if (!this->pDir)
{
return {};
}
auto pNext = this->pDir->Next();
while (!pNext)
{
DoNext();
if (!this->pDir)
{
return {};
}
pNext = this->pDir->Next();
}
if (curSubDir.size())
{
pNext->fileName.insert(pNext->fileName.begin(), curSubDir.begin(), curSubDir.end());
}
if (pNext->bExistsDirectory)
{
nextLevel.push_back(pNext->fileName + "/");
nextLevel2.push_back(pNext->fileName + "/");
}
else
{
AuFS::Remove(pNext->path);
}
return pNext;
}
void RemoveDirs()
{
for (auto itr = nextLevel2.rbegin(); itr != nextLevel2.rend(); itr++)
{
AuFS::Remove(curPath + "/" + itr->c_str());
}
}
};
AUKN_SYM bool DirDeleter(const AuString &string)
{
auto pObj = AuMakeShared<RecursiveDirDeleter>();
if (!pObj)
{
SysPushErrorMem();
return {};
}
if (!pObj->OpenDir(string))
{
return {};
}
while (pObj->Next())
{
}
pObj->RemoveDirs();
AuFS::Remove(string);
return !AuFS::DirExists(string);
}
}

View File

@ -0,0 +1,13 @@
/***
Copyright (C) 2022 J Reece Wilson (a/k/a "Reece"). All rights reserved.
File: DirDeleter.hpp
Date: 2022-11-06
Author: Reece
***/
#pragma once
namespace Aurora::IO::FS
{
}

View File

@ -0,0 +1,98 @@
/***
Copyright (C) 2022 J Reece Wilson (a/k/a "Reece"). All rights reserved.
File: FSRecursion.cpp
Date: 2022-11-06
Author: Reece
***/
#include <Source/RuntimeInternal.hpp>
#include "FS.hpp"
namespace Aurora::IO::FS
{
struct RecursiveDirIterator : IReadDir
{
AuSPtr<IReadDir> pDir;
AuList<AuString> nextLevel;
AuString curPath;
AuString curSubDir;
bool OpenDir(const AuString &str)
{
curPath = str;
pDir = ReadDir(str);
return bool(pDir);
}
bool OpenNext(const AuString &str)
{
curPath = str;
pDir = ReadDir(str);
return bool(pDir);
}
void DoNext()
{
this->pDir.reset();
if (!nextLevel.size())
{
return;
}
auto a = nextLevel[0];
nextLevel.erase(nextLevel.begin());
pDir = ReadDir(curPath + "/" + a);
curSubDir = a;
}
virtual StatEx *Next() override
{
if (!this->pDir)
{
return {};
}
auto pNext = this->pDir->Next();
while (!pNext)
{
DoNext();
if (!this->pDir)
{
return {};
}
pNext = this->pDir->Next();
}
if (curSubDir.size())
{
pNext->fileName.insert(pNext->fileName.begin(), curSubDir.begin(), curSubDir.end());
}
if (pNext->bExistsDirectory)
{
nextLevel.push_back(pNext->fileName + "/");
}
return pNext;
}
};
AUKN_SYM AuSPtr<IReadDir> ReadDirRecursive(const AuString &string)
{
auto pObj = AuMakeShared<RecursiveDirIterator>();
if (!pObj)
{
SysPushErrorMem();
return {};
}
if (!pObj->OpenDir(string))
{
return {};
}
return pObj;
}
}

View File

@ -0,0 +1,13 @@
/***
Copyright (C) 2022 J Reece Wilson (a/k/a "Reece"). All rights reserved.
File: FSRecursion.hpp
Date: 2022-11-06
Author: Reece
***/
#pragma once
namespace Aurora::IO::FS
{
}

View File

@ -78,6 +78,7 @@ namespace Aurora::Threading::Primitives
bool RWLockImpl::LockRead(AuUInt64 timeout)
{
#if 0
AU_LOCK_GUARD(mutex_);
if (this->state_ == -1 && this->reentrantWriteLockHandle_ == AuThreads::GetThreadId())
@ -102,11 +103,53 @@ namespace Aurora::Threading::Primitives
}
this->state_++;
#else
if (this->state_ == -1 && this->reentrantWriteLockHandle_ == AuThreads::GetThreadId())
{
return true;
}
AuInt32 iCurState {};
do
{
iCurState = this->state_;
if (iCurState < 0)
{
AU_LOCK_GUARD(this->mutex_);
iCurState = this->state_;
if (iCurState < 0)
{
if (!this->condition_->WaitForSignal(timeout))
{
return false;
}
if (this->writersPending_)
{
this->condition_->Broadcast();
continue;
}
return true;
}
}
}
while (AuAtomicCompareExchange(&this->state_, iCurState + 1, iCurState) != iCurState);
#endif
return true;
}
bool RWLockImpl::LockWrite(AuUInt64 timeout)
{
if (AuAtomicCompareExchange(&this->state_, -1, 0) == 0)
{
return true;
}
AU_LOCK_GUARD(this->mutex_);
this->writersPending_++;
@ -127,14 +170,14 @@ namespace Aurora::Threading::Primitives
bool RWLockImpl::TryLockRead()
{
if (this->state_ == -1)
auto iCurState = this->state_;
if (iCurState == -1)
{
return this->reentrantWriteLockHandle_ == AuThreads::GetThreadId();
}
AU_LOCK_GUARD(mutex_);
this->state_++;
return true;
return AuAtomicCompareExchange(&this->state_, iCurState + 1, iCurState) != iCurState;
}
bool RWLockImpl::TryLockWrite()
@ -227,23 +270,23 @@ namespace Aurora::Threading::Primitives
AUKN_SYM IRWLock *RWLockNew()
{
auto ret = _new RWLockImpl();
if (!ret)
auto pRwLock = _new RWLockImpl();
if (!pRwLock)
{
return nullptr;
}
if (!ret->Init())
if (!pRwLock->Init())
{
delete ret;
delete pRwLock;
return nullptr;
}
return ret;
return pRwLock;
}
AUKN_SYM void RWLockRelease(IRWLock *waitable)
AUKN_SYM void RWLockRelease(IRWLock *pRwLock)
{
AuSafeDelete<RWLockImpl *>(waitable);
AuSafeDelete<RWLockImpl *>(pRwLock);
}
}