[+] 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()
|
// (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 ©Block)
|
MemoryView(T *start, AuUInt length, const MemoryControlBlock ©Block)
|
||||||
@ -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>;
|
||||||
|
Loading…
Reference in New Issue
Block a user