Skip to content

Commit

Permalink
Merge pull request #31932 from huisedenanhai/master
Browse files Browse the repository at this point in the history
make core/Reference thread safe
  • Loading branch information
akien-mga committed Sep 26, 2019
2 parents fba8ee4 + 124e51f commit 202440a
Show file tree
Hide file tree
Showing 3 changed files with 16 additions and 13 deletions.
18 changes: 8 additions & 10 deletions core/reference.cpp
Expand Up @@ -36,12 +36,7 @@ bool Reference::init_ref() {

if (reference()) {

// this may fail in the scenario of two threads assigning the pointer for the FIRST TIME
// at the same time, which is never likely to happen (would be crazy to do)
// so don't do it.

if (refcount_init.get() > 0) {
refcount_init.unref();
if (!is_referenced() && refcount_init.unref()) {
unreference(); // first referencing is already 1, so compensate for the ref above
}

Expand All @@ -64,9 +59,11 @@ int Reference::reference_get_count() const {
}

bool Reference::reference() {
bool success = refcount.ref();

if (success && refcount.get() <= 2 /* higher is not relevant */) {
uint32_t rc_val = refcount.refval();
bool success = rc_val != 0;

if (success && rc_val <= 2 /* higher is not relevant */) {
if (get_script_instance()) {
get_script_instance()->refcount_incremented();
}
Expand All @@ -84,9 +81,10 @@ bool Reference::reference() {

bool Reference::unreference() {

bool die = refcount.unref();
uint32_t rc_val = refcount.unrefval();
bool die = rc_val == 0;

if (refcount.get() <= 1 /* higher is not relevant */) {
if (rc_val <= 1 /* higher is not relevant */) {
if (get_script_instance()) {
bool script_ret = get_script_instance()->refcount_decremented();
die = die && script_ret;
Expand Down
2 changes: 1 addition & 1 deletion core/reference.h
Expand Up @@ -47,7 +47,7 @@ class Reference : public Object {
static void _bind_methods();

public:
_FORCE_INLINE_ bool is_referenced() const { return refcount_init.get() < 1; }
_FORCE_INLINE_ bool is_referenced() const { return refcount_init.get() != 1; }
bool init_ref();
bool reference(); // returns false if refcount is at zero and didn't get increased
bool unreference();
Expand Down
9 changes: 7 additions & 2 deletions core/safe_refcount.h
Expand Up @@ -177,12 +177,12 @@ struct SafeRefCount {
public:
// destroy() is called when weak_count_ drops to zero.

_ALWAYS_INLINE_ bool ref() { //true on success
_ALWAYS_INLINE_ bool ref() { // true on success

return atomic_conditional_increment(&count) != 0;
}

_ALWAYS_INLINE_ uint32_t refval() { //true on success
_ALWAYS_INLINE_ uint32_t refval() { // none-zero on success

return atomic_conditional_increment(&count);
}
Expand All @@ -192,6 +192,11 @@ struct SafeRefCount {
return atomic_decrement(&count) == 0;
}

_ALWAYS_INLINE_ uint32_t unrefval() { // 0 if must be disposed of

return atomic_decrement(&count);
}

_ALWAYS_INLINE_ uint32_t get() const { // nothrow

return count;
Expand Down

0 comments on commit 202440a

Please sign in to comment.