Merge pull request #64795 from RandomShaper/fix_saferefcount

Prevent misuse of SafeRefCount
This commit is contained in:
Rémi Verschelde 2023-01-09 14:18:53 +01:00
commit d46568205d
No known key found for this signature in database
GPG key ID: C3336907360768E1
2 changed files with 27 additions and 7 deletions

View file

@ -33,6 +33,10 @@
#include "core/typedefs.h"
#ifdef DEV_ENABLED
#include "core/error/error_macros.h"
#endif
#include <atomic>
#include <type_traits>
@ -163,6 +167,16 @@ public:
class SafeRefCount {
SafeNumeric<uint32_t> count;
#ifdef DEV_ENABLED
_ALWAYS_INLINE_ void _check_unref_sanity() {
// This won't catch every misuse, but it's better than nothing.
CRASH_COND_MSG(count.get() == 0,
"Trying to unreference a SafeRefCount which is already zero is wrong and a symptom of it being misused.\n"
"Upon a SafeRefCount reaching zero any object whose lifetime is tied to it, as well as the ref count itself, must be destroyed.\n"
"Moreover, to guarantee that, no multiple threads should be racing to do the final unreferencing to zero.");
}
#endif
public:
_ALWAYS_INLINE_ bool ref() { // true on success
return count.conditional_increment() != 0;
@ -173,10 +187,16 @@ public:
}
_ALWAYS_INLINE_ bool unref() { // true if must be disposed of
#ifdef DEV_ENABLED
_check_unref_sanity();
#endif
return count.decrement() == 0;
}
_ALWAYS_INLINE_ uint32_t unrefval() { // 0 if must be disposed of
#ifdef DEV_ENABLED
_check_unref_sanity();
#endif
return count.decrement();
}