From c686e59fd6677e88b755626844bf643b19835c3d Mon Sep 17 00:00:00 2001 From: Ari Vuollet Date: Wed, 13 Sep 2023 17:22:19 +0300 Subject: [PATCH] Lazy allocate mutex in `Delegate` --- Source/Engine/Core/Delegate.h | 65 +++++++++++++++++++++++++++-------- 1 file changed, 51 insertions(+), 14 deletions(-) diff --git a/Source/Engine/Core/Delegate.h b/Source/Engine/Core/Delegate.h index 1b7a28c48..1600f7ced 100644 --- a/Source/Engine/Core/Delegate.h +++ b/Source/Engine/Core/Delegate.h @@ -290,19 +290,14 @@ protected: intptr volatile _size = 0; #else HashSet* _functions = nullptr; - CriticalSection* _locker; - int32* _lockerRefCount; + CriticalSection* _locker = nullptr; + int32* _lockerRefCount = nullptr; #endif typedef void (*StubSignature)(void*, Params...); public: Delegate() { -#if !DELEGATE_USE_ATOMIC - _locker = New(); - _lockerRefCount = New(); - *_lockerRefCount = 1; -#endif } Delegate(const Delegate& other) @@ -366,14 +361,17 @@ public: Allocator::Free((void*)_ptr); } #else - int32& lockerRefCount = *_lockerRefCount; - lockerRefCount--; - if (lockerRefCount == 0) + if (_locker != nullptr) { - Allocator::Free(_locker); - Allocator::Free(_lockerRefCount); - _locker = nullptr; - _lockerRefCount = nullptr; + int32& lockerRefCount = *_lockerRefCount; + lockerRefCount--; + if (lockerRefCount == 0) + { + Allocator::Free(_locker); + Allocator::Free(_lockerRefCount); + _locker = nullptr; + _lockerRefCount = nullptr; + } } if (_functions != nullptr) { @@ -383,6 +381,7 @@ public: i->Item.LambdaCtor(); } Allocator::Free(_functions); + _functions = nullptr; } #endif } @@ -522,6 +521,12 @@ public: Allocator::Free(bindings); } #else + if (_locker == nullptr) + { + _locker = New(); + _lockerRefCount = New(); + *_lockerRefCount = 1; + } ScopeLock lock(*_locker); if (_functions == nullptr) _functions = New>(32); @@ -581,6 +586,12 @@ public: } } #else + if (_locker == nullptr) + { + _locker = New(); + _lockerRefCount = New(); + *_lockerRefCount = 1; + } ScopeLock lock(*_locker); if (_functions && _functions->Contains(f)) return; @@ -594,9 +605,18 @@ public: template void Unbind() { +#if DELEGATE_USE_ATOMIC FunctionType f; f.template Bind(); Unbind(f); +#else + if (_functions == nullptr) + return; + FunctionType f; + f.template Bind(); + ScopeLock lock(*_locker); + _functions->Remove(f); +#endif } /// @@ -606,9 +626,18 @@ public: template void Unbind(T* callee) { +#if DELEGATE_USE_ATOMIC FunctionType f; f.template Bind(callee); Unbind(f); +#else + if (_functions == nullptr) + return; + FunctionType f; + f.template Bind(callee); + ScopeLock lock(*_locker); + _functions->Remove(f); +#endif } /// @@ -617,8 +646,16 @@ public: /// The method. void Unbind(Signature method) { +#if DELEGATE_USE_ATOMIC FunctionType f(method); Unbind(f); +#else + if (_functions == nullptr) + return; + FunctionType f(method); + ScopeLock lock(*_locker); + _functions->Remove(f); +#endif } ///