[+] MemoryView::ToSharedControlBlock

[+] et al
This commit is contained in:
Reece Wilson 2024-06-29 01:05:29 +01:00
parent 035d822ec1
commit 27b18c0a37

View File

@ -26,6 +26,21 @@ namespace Aurora::Memory
// (Consider inverse construction order, for instance, we'd have to always call MemoryView::ResetControlBlock()
// in a derived subclass, in order release the pInUseCounter reference before the derived shared members get released)
AuSPtr<void> pPinner; // WARNING: as usual, std types don't validate their allocator, and our shared ptrs can be different between binaries!
~MemoryControlBlock()
{
this->Release();
}
void Release()
{
if (auto pCounter = AuExchange(this->pInUseCounter, nullptr))
{
AuAtomicSub(pCounter, 1u);
}
AuResetMember(this->pPinner);
}
};
template<bool Readonly_b>
@ -216,11 +231,6 @@ namespace Aurora::Memory
this->controlBlock.pPinner = pRAIIOwner;
}
~MemoryView()
{
this->ResetControlBlock();
}
private:
template<typename T>
MemoryView(T *start, AuUInt length, const MemoryControlBlock &copyBlock)
@ -382,11 +392,15 @@ namespace Aurora::Memory
return MemoryView(MemoryView(pData.get(), uLength), pData);
}
bool CloneSelf()
bool TryCloneSelf(bool bResetOnFailure = true)
{
auto replacement = Clone();
if (!replacement)
{
if (bResetOnFailure)
{
AuResetMember(*this);
}
return false;
}
AuResetMember(*this, replacement);
@ -407,17 +421,6 @@ namespace Aurora::Memory
private:
MemoryControlBlock controlBlock;
protected:
void ResetControlBlock()
{
if (auto pCounter = AuExchange(this->controlBlock.pInUseCounter, nullptr))
{
AuAtomicSub(pCounter, 1u);
}
AuResetMember(this->controlBlock.pPinner);
}
public:
bool HasControlBlock() const
{
@ -467,6 +470,21 @@ namespace Aurora::Memory
#endif
}
AuSPtr<MemoryView> TryPromoteToSharedViewNoParentNesting(AuSPtr<void> pParent = {})
{
if (this->HasControlBlock())
{
return AuMakeShared<MemoryView>(*this);
}
if (pParent)
{
return AuMakeShared<MemoryView>(*this, pParent);
}
return {};
}
bool TryDemoteFromSharedView(const AuSPtr<MemoryView> &pCopy)
{
if (pCopy && pCopy->HasControlBlock())
@ -480,6 +498,19 @@ namespace Aurora::Memory
}
}
bool TryDemoteFromReference(const MemoryView &refCopy)
{
if (refCopy.HasControlBlock())
{
AuResetMember(*this, refCopy);
return true;
}
else
{
return false;
}
}
void DemoteFromSharedView(const AuSPtr<MemoryView> &pCopy)
{
if (!pCopy)
@ -497,6 +528,39 @@ namespace Aurora::Memory
AuResetMember(*this, AuConstReference(*pCopy.get()), pCopy);
}
}
AuSPtr<void> ToSharedControlBlock(bool *pbFailed = nullptr)
{
if (pbFailed)
{
*pbFailed = false;
}
if (this->controlBlock.pInUseCounter)
{
auto pShared = AuMakeShared<MemoryControlBlock>();
if (!pShared)
{
if (pbFailed)
{
*pbFailed = true;
}
return {};
}
AuAtomicAdd(&this->controlBlock.pInUseCounter, 1u);
pShared->pInUseCounter = this->controlBlock.pInUseCounter;
pShared->pPinner = this->controlBlock.pPinner;
return pShared;
}
if (this->controlBlock.pPinner)
{
return this->controlBlock.pPinner;
}
return {};
}
};
using MemoryViewRead = MemoryView<true>;