Merge branch 'mutex_delegate_fixes' of https://github.com/GoaLitiuM/FlaxEngine into GoaLitiuM-mutex_delegate_fixes

This commit is contained in:
Wojtek Figat
2023-09-27 22:42:23 +02:00

View File

@@ -290,19 +290,13 @@ protected:
intptr volatile _size = 0; intptr volatile _size = 0;
#else #else
HashSet<FunctionType>* _functions = nullptr; HashSet<FunctionType>* _functions = nullptr;
CriticalSection* _locker; CriticalSection* _locker = nullptr;
int32* _lockerRefCount;
#endif #endif
typedef void (*StubSignature)(void*, Params...); typedef void (*StubSignature)(void*, Params...);
public: public:
Delegate() Delegate()
{ {
#if !DELEGATE_USE_ATOMIC
_locker = New<CriticalSection>();
_lockerRefCount = New<int32>();
*_lockerRefCount = 1;
#endif
} }
Delegate(const Delegate& other) Delegate(const Delegate& other)
@@ -329,8 +323,6 @@ public:
i->Item.LambdaCtor(); i->Item.LambdaCtor();
} }
_locker = other._locker; _locker = other._locker;
_lockerRefCount = other._lockerRefCount;
*_lockerRefCount = *_lockerRefCount + 1;
#endif #endif
} }
@@ -344,10 +336,8 @@ public:
#else #else
_functions = other._functions; _functions = other._functions;
_locker = other._locker; _locker = other._locker;
_lockerRefCount = other._lockerRefCount;
other._functions = nullptr; other._functions = nullptr;
other._locker = nullptr; other._locker = nullptr;
other._lockerRefCount = nullptr;
#endif #endif
} }
@@ -366,14 +356,10 @@ public:
Allocator::Free((void*)_ptr); Allocator::Free((void*)_ptr);
} }
#else #else
int32& lockerRefCount = *_lockerRefCount; if (_locker != nullptr)
lockerRefCount--;
if (lockerRefCount == 0)
{ {
Allocator::Free(_locker); Allocator::Free(_locker);
Allocator::Free(_lockerRefCount);
_locker = nullptr; _locker = nullptr;
_lockerRefCount = nullptr;
} }
if (_functions != nullptr) if (_functions != nullptr)
{ {
@@ -383,6 +369,7 @@ public:
i->Item.LambdaCtor(); i->Item.LambdaCtor();
} }
Allocator::Free(_functions); Allocator::Free(_functions);
_functions = nullptr;
} }
#endif #endif
} }
@@ -417,10 +404,8 @@ public:
#else #else
_functions = other._functions; _functions = other._functions;
_locker = other._locker; _locker = other._locker;
_lockerRefCount = other._lockerRefCount;
other._functions = nullptr; other._functions = nullptr;
other._locker = nullptr; other._locker = nullptr;
other._lockerRefCount = nullptr;
#endif #endif
} }
return *this; return *this;
@@ -522,6 +507,8 @@ public:
Allocator::Free(bindings); Allocator::Free(bindings);
} }
#else #else
if (_locker == nullptr)
_locker = New<CriticalSection>();
ScopeLock lock(*_locker); ScopeLock lock(*_locker);
if (_functions == nullptr) if (_functions == nullptr)
_functions = New<HashSet<FunctionType>>(32); _functions = New<HashSet<FunctionType>>(32);
@@ -581,6 +568,8 @@ public:
} }
} }
#else #else
if (_locker == nullptr)
_locker = New<CriticalSection>();
ScopeLock lock(*_locker); ScopeLock lock(*_locker);
if (_functions && _functions->Contains(f)) if (_functions && _functions->Contains(f))
return; return;
@@ -594,9 +583,18 @@ public:
template<void(*Method)(Params...)> template<void(*Method)(Params...)>
void Unbind() void Unbind()
{ {
#if DELEGATE_USE_ATOMIC
FunctionType f; FunctionType f;
f.template Bind<Method>(); f.template Bind<Method>();
Unbind(f); Unbind(f);
#else
if (_functions == nullptr)
return;
FunctionType f;
f.template Bind<Method>();
ScopeLock lock(*_locker);
_functions->Remove(f);
#endif
} }
/// <summary> /// <summary>
@@ -606,9 +604,18 @@ public:
template<class T, void(T::*Method)(Params...)> template<class T, void(T::*Method)(Params...)>
void Unbind(T* callee) void Unbind(T* callee)
{ {
#if DELEGATE_USE_ATOMIC
FunctionType f; FunctionType f;
f.template Bind<T, Method>(callee); f.template Bind<T, Method>(callee);
Unbind(f); Unbind(f);
#else
if (_functions == nullptr)
return;
FunctionType f;
f.template Bind<T, Method>(callee);
ScopeLock lock(*_locker);
_functions->Remove(f);
#endif
} }
/// <summary> /// <summary>
@@ -617,8 +624,16 @@ public:
/// <param name="method">The method.</param> /// <param name="method">The method.</param>
void Unbind(Signature method) void Unbind(Signature method)
{ {
#if DELEGATE_USE_ATOMIC
FunctionType f(method); FunctionType f(method);
Unbind(f); Unbind(f);
#else
if (_functions == nullptr)
return;
FunctionType f(method);
ScopeLock lock(*_locker);
_functions->Remove(f);
#endif
} }
/// <summary> /// <summary>