[+] 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() // (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) // 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! 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> template<bool Readonly_b>
@ -216,11 +231,6 @@ namespace Aurora::Memory
this->controlBlock.pPinner = pRAIIOwner; this->controlBlock.pPinner = pRAIIOwner;
} }
~MemoryView()
{
this->ResetControlBlock();
}
private: private:
template<typename T> template<typename T>
MemoryView(T *start, AuUInt length, const MemoryControlBlock &copyBlock) MemoryView(T *start, AuUInt length, const MemoryControlBlock &copyBlock)
@ -382,11 +392,15 @@ namespace Aurora::Memory
return MemoryView(MemoryView(pData.get(), uLength), pData); return MemoryView(MemoryView(pData.get(), uLength), pData);
} }
bool CloneSelf() bool TryCloneSelf(bool bResetOnFailure = true)
{ {
auto replacement = Clone(); auto replacement = Clone();
if (!replacement) if (!replacement)
{ {
if (bResetOnFailure)
{
AuResetMember(*this);
}
return false; return false;
} }
AuResetMember(*this, replacement); AuResetMember(*this, replacement);
@ -407,17 +421,6 @@ namespace Aurora::Memory
private: private:
MemoryControlBlock controlBlock; MemoryControlBlock controlBlock;
protected:
void ResetControlBlock()
{
if (auto pCounter = AuExchange(this->controlBlock.pInUseCounter, nullptr))
{
AuAtomicSub(pCounter, 1u);
}
AuResetMember(this->controlBlock.pPinner);
}
public: public:
bool HasControlBlock() const bool HasControlBlock() const
{ {
@ -467,6 +470,21 @@ namespace Aurora::Memory
#endif #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) bool TryDemoteFromSharedView(const AuSPtr<MemoryView> &pCopy)
{ {
if (pCopy && pCopy->HasControlBlock()) 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) void DemoteFromSharedView(const AuSPtr<MemoryView> &pCopy)
{ {
if (!pCopy) if (!pCopy)
@ -497,6 +528,39 @@ namespace Aurora::Memory
AuResetMember(*this, AuConstReference(*pCopy.get()), pCopy); 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>; using MemoryViewRead = MemoryView<true>;