[*] Ensure shared pointers aren't freed between conflicting default heaps

This commit is contained in:
Reece Wilson 2024-06-11 09:36:34 +01:00
parent f6bcade29c
commit bea0f5c8f2
3 changed files with 206 additions and 135 deletions

View File

@ -88,3 +88,7 @@
//#define _AURORA_AVOID_DUMB_STL_TYPES
#define _AURORA_AVOID_EXTREMLY_DUMB_STL_TYPES
// TODO:
#if !defined(_AURORA_NULLEXPT_BRANCH)
#define _AURORA_NULLEXPT_BRANCH
#endif

View File

@ -369,20 +369,6 @@ namespace Aurora::Memory
}
}
auline void throwif()
{
if (!cached) [[unlikely]]
{
#if defined(_AURORA_NULLEXPT_BRANCH_BUG_CHECK)
cached = Base_t::operator bool();
if (!cached) [[likely]]
#endif
{
AU_THROW_STRING("ExSharedPointer Null Access Violation");
}
}
}
auline void _cache()
{
cached = Base_t::operator bool();

View File

@ -27,13 +27,6 @@ using AuWPtr = AURORA_RUNTIME_AU_WEAK_PTR<T>;
#define AURORA_RUNTIME_AU_UNIQUE_PTR std::unique_ptr
#endif
#if !defined(AURORA_RUNTIME_AU_DEFAULT_DELETER)
#define AURORA_RUNTIME_AU_DEFAULT_DELETER std::default_delete
#endif
template <class T>
using AuDefaultDeleter = AURORA_RUNTIME_AU_DEFAULT_DELETER<T>;
#include "STLShims/ExtendStlLikeSharedPtr.hpp"
template <class T>
@ -66,111 +59,6 @@ static auline void AuMemoryPanic(const char *msg)
#endif
}
template <class T, typename... Args>
static auline AuSPtr<T> AuMakeShared(Args&&... args)
{
try
{
return AURORA_RUNTIME_MAKE_SHARED<T>(AuForward<Args>(args)...);
}
catch (...)
{
return {};
}
}
template <class T, typename... Args>
static auline AuSPtr<T> AuMakeSharedPanic(Args&&... args)
{
try
{
auto pShared = AURORA_RUNTIME_MAKE_SHARED<T>(AuForward<Args>(args)...);
if (!pShared)
{
AuMemoryPanic("Failed to allocate <X>"); // TODO: non-rtti typename
}
return pShared;
}
catch (...)
{
AuMemoryPanic("Failed to allocate <X>"); // TODO: non-rtti typename
return {};
}
}
template <class T, typename... Args>
static auline AuSPtr<T> AuMakeSharedThrow(Args&&... args)
{
try
{
auto pShared = AURORA_RUNTIME_MAKE_SHARED<T>(AuForward<Args>(args)...);
if (!pShared)
{
// TODO: Agnostic SysPushErrorMemory
AU_THROW_STRING("Failed to allocate <X>"); // TODO: non-rtti typename
}
return pShared;
}
catch (...)
{
// TODO: Agnostic SysPushErrorCatch
AU_THROW_STRING("Failed to allocate <X>"); // TODO: non-rtti typename
return {};
}
}
namespace __audetail
{
struct Dummy
{
char a;
};
inline AuSPtr<Dummy> GetDummyDeleter()
{
static AuSPtr<Dummy> d;
if (!d)
{
#if defined(AURORA_COMPILER_MSVC)
return d;
#endif
d = AuMakeShared<Dummy>();
}
return d;
}
}
template <class T>
static auline AuSPtr<T> AuMakeSharedArray(AuUInt count)
{
try
{
#if defined(AU_LANG_CPP_20) && 0
return AURORA_RUNTIME_AU_SHARED_PTR<T[]>(count);
#else
return AURORA_RUNTIME_AU_SHARED_PTR<T>(new T[count], AuDefaultDeleter<T[]>());
#endif
}
catch (...)
{
return {};
}
}
template <class T>
static AuSPtr<T> AuUnsafeRaiiToShared(T *in)
{
return AuSPtr<T>(__audetail::GetDummyDeleter(), in);
}
template <class T, class Z>
static AuSPtr<T> AuUnsafeRaiiToShared(const AuUPtr<T, Z> &in)
{
return AuUnsafeRaiiToShared(in.get());
}
template <class T, AuUInt Z>
static constexpr AuUInt AuArraySize(const T(&array)[Z])
{
@ -240,6 +128,9 @@ static void auline AuSafeDelete(T *in)
delete static_cast<Z>(in);
}
#if !defined(AURORA_RUNTIME_AU_DEFAULT_DELETER)
#define AURORA_RUNTIME_AU_DEFAULT_DELETER std::default_delete
#endif
// TODO: Move me
#include "auOptional.hpp"
@ -274,13 +165,12 @@ namespace Aurora::Memory
AU_COPY_MOVE(BaseAuroraRuntimeAllocator)
constexpr BaseAuroraRuntimeAllocator()
{}
constexpr BaseAuroraRuntimeAllocator() noexcept
{ }
template <class U>
constexpr BaseAuroraRuntimeAllocator(const BaseAuroraRuntimeAllocator <U> &) noexcept
{
}
{ }
void *allocate_bytes(std::size_t nbytes,
std::size_t alignment = alignof(std::max_align_t))
@ -386,17 +276,208 @@ namespace Aurora::Memory
};
template<typename T>
using PrimitiveArrayAllocator = BaseAuroraRuntimeAllocator<T>;
using PrimitiveArrayAllocator = BaseAuroraRuntimeAllocator<T>;
template<typename T>
using ClassArrayAllocator = BaseAuroraRuntimeAllocator<T>;
using ClassArrayAllocator = BaseAuroraRuntimeAllocator<T>;
template<typename T>
using StringAllocator = BaseAuroraRuntimeAllocator<T>;
using StringAllocator = BaseAuroraRuntimeAllocator<T>;
template<typename T>
using SharedControlBlockAllocator = BaseAuroraRuntimeAllocator<T>;
template <class T>
struct DefaultRuntimeDeleter
{
constexpr DefaultRuntimeDeleter() noexcept = default;
template <class Z>
DefaultRuntimeDeleter(const DefaultRuntimeDeleter<Z> &) noexcept
{ }
void operator()(T *pThat) const
{
if constexpr (AuIsClass_v<T> &&
!AuIsTriviallyDestructible_v<T>)
{
pThat->~T();
}
Aurora::Memory::__Free(pThat);
}
};
template <class T>
struct DefaultRuntimeDeleter<T[]>
{
constexpr DefaultRuntimeDeleter() noexcept = default;
template <class Z>
DefaultRuntimeDeleter(const DefaultRuntimeDeleter<Z> &) noexcept
{ }
template <class Z>
void operator()(Z *pThat) const
{
AURORA_RUNTIME_AU_DEFAULT_DELETER<T[]>()(pThat);
}
};
#endif
}
#if defined(AURORA_ROXTL_ALLOCATORS_USE_STD)
template <class T>
using AuDefaultDeleter = AURORA_RUNTIME_AU_DEFAULT_DELETER<T>;
#else
template <class T>
using AuDefaultDeleter = Aurora::Memory::DefaultRuntimeDeleter<T>;
#endif
template <class T, typename... Args>
static auline AuSPtr<T> AuMakeShared(Args&&... args)
{
using Z = AuRemoveConst_t<T>;
try
{
#if defined(AURORA_ROXTL_ALLOCATORS_USE_STD)
return AURORA_RUNTIME_MAKE_SHARED<T>(AuForward<Args>(args)...);
#else
auto pNext = Aurora::Memory::__FAlloc(sizeof(T), alignof(T));
if (!pNext)
{
return nullptr;
}
auto pNextClass = (Z *)pNext;
new (pNextClass) Z (AuForward<Args>(args)...);
return std::shared_ptr<T>(pNextClass, Aurora::Memory::DefaultRuntimeDeleter<Z> {}, Aurora::Memory::SharedControlBlockAllocator<T> {});
#endif
}
catch (...)
{
return {};
}
}
template <class T, typename... Args>
static auline AuSPtr<T> AuMakeSharedPanic(Args&&... args)
{
#if defined(AURORA_ROXTL_ALLOCATORS_USE_STD)
try
{
auto pShared = AURORA_RUNTIME_MAKE_SHARED<T>(AuForward<Args>(args)...);
if (!pShared)
{
AuMemoryPanic("Failed to allocate <X>"); // TODO: non-rtti typename
}
return pShared;
}
catch (...)
{
AuMemoryPanic("Failed to allocate <X>"); // TODO: non-rtti typename
return {};
}
#else
auto pShared = AuMakeShared<T>(AuForward<Args>(args)...);
if (!pShared)
{
AuMemoryPanic("Failed to allocate <X>"); // TODO: non-rtti typename
}
return pShared;
#endif
}
template <class T, typename... Args>
static auline AuSPtr<T> AuMakeSharedThrow(Args&&... args)
{
#if defined(AURORA_ROXTL_ALLOCATORS_USE_STD)
try
{
auto pShared = AURORA_RUNTIME_MAKE_SHARED<T>(AuForward<Args>(args)...);
if (!pShared)
{
// TODO: Agnostic SysPushErrorMemory
AU_THROW_STRING("Failed to allocate <X>"); // TODO: non-rtti typename
}
return pShared;
}
catch (...)
{
// TODO: Agnostic SysPushErrorCatch
AU_THROW_STRING("Failed to allocate <X>"); // TODO: non-rtti typename
return {};
}
#else
auto pShared = AuMakeShared<T>(AuForward<Args>(args)...);
if (!pShared)
{
AU_THROW_STRING("Failed to allocate <X>"); // TODO: non-rtti typename
}
return pShared;
#endif
}
template <class T>
static auline AuSPtr<T> AuMakeSharedArray(AuUInt count)
{
try
{
#if defined(AU_LANG_CPP_20) && 0
return AURORA_RUNTIME_AU_SHARED_PTR<T[]>(count);
#else
return AURORA_RUNTIME_AU_SHARED_PTR<T>(new T[count], AURORA_RUNTIME_AU_DEFAULT_DELETER<T[]>());
#endif
}
catch (...)
{
return {};
}
}
namespace __audetail
{
struct Dummy
{
char a;
};
inline AuSPtr<Dummy> GetDummyDeleter()
{
static AuSPtr<Dummy> d;
if (!d)
{
#if defined(AURORA_COMPILER_MSVC)
return d;
#endif
d = AuMakeShared<Dummy>();
}
return d;
}
}
template <class T>
static AuSPtr<T> AuUnsafeRaiiToShared(T *in)
{
return AuSPtr<T>(__audetail::GetDummyDeleter(), in);
}
template <class T, class Z>
static AuSPtr<T> AuUnsafeRaiiToShared(const AuUPtr<T, Z> &in)
{
return AuUnsafeRaiiToShared(in.get());
}
template <class T, class Z>
inline constexpr bool operator==(const Aurora::Memory::BaseAuroraRuntimeAllocator<T> &lhs,
const Aurora::Memory::BaseAuroraRuntimeAllocator<Z> &rhs) noexcept