[+] MemoryView::ToSharedControlBlock
[+] et al
This commit is contained in:
parent
035d822ec1
commit
27b18c0a37
@ -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 ©Block)
|
||||
@ -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>;
|
||||
|
Loading…
Reference in New Issue
Block a user