• Create Account

### #ActualAndreas Jonsson

Posted 18 July 2013 - 04:20 PM

Yes, with a lockable critical section in the shared boolean I now believe the solution is thread-safe. Here's what the test class above now looks like (note, I didn't bother making the refCount itself thread-safe, but that is easily done with atomic instructions):

class MyClass
{
public:
MyClass() { refCount = 1; weakRefFlag = 0; }
~MyClass()
{
if( weakRefFlag )
weakRefFlag->Release();
}
void Release()
{
// If the weak ref flag exists it is because someone held a weak ref
// and that someone may add a reference to the object at any time. It
// is ok to check the existance of the weakRefFlag without locking here
// because if the refCount is 1 then no other thread is currently
// creating the weakRefFlag.
if( refCount == 1 && weakRefFlag )
{
// Set the flag to tell others that the object is no longer alive
// We must do this before decreasing the refCount to 0 so we don't
// end up with a race condition between this thread attempting to
// destroy the object and the other that temporary added a strong
// ref from the weak ref.
weakRefFlag->Set(true);
}

if( --refCount == 0 )
delete this;
}
asILockableSharedBool *GetWeakRefFlag()
{
if( !weakRefFlag )
{
// Lock globally so no other thread can attempt
// to create a shared bool at the same time
asAcquireExclusiveLock();

// Make sure another thread didn't create the
// flag while we waited for the lock
if( !weakRefFlag )
weakRefFlag = asCreateLockableSharedBool();

asReleaseExclusiveLock();
}

return weakRefFlag;
}

static MyClass *Factory() { return new MyClass(); }

protected:
int refCount;
asILockableSharedBool *weakRefFlag;
};



The implementation of the weakref add-on can be seen in the SVN.

If anyone can think of why this wouldn't be thread-safe, please let me know so I can fix it before releasing version 2.27.0. If you can think of a better solution I would also very much like to see that.

### #1Andreas Jonsson

Posted 18 July 2013 - 04:18 PM

Yes, with a lockable critical section in the shared boolean I now believe the solution is thread-safe. Here's what the test class above now looks like (note, I didn't bother making the refCount itself thread-safe, but that is easily done with atomic instructions):

class MyClass
{
public:
MyClass() { refCount = 1; weakRefFlag = 0; }
~MyClass()
{
if( weakRefFlag )
weakRefFlag->Release();
}
void Release()
{
// If the weak ref flag exists it is because someone held a weak ref
// and that someone may add a reference to the object at any time. It
// is ok to check the existance of the weakRefFlag without locking here
// because if the refCount is 1 then no other thread is currently
// creating the weakRefFlag.
if( refCount == 1 && weakRefFlag )
{
// Set the flag to tell others that the object is no longer alive
// We must do this before decreasing the refCount to 0 so we don't
// end up with a race condition between this thread attempting to
// destroy the object and the other that temporary added a strong
// ref from the weak ref.
weakRefFlag->Set(true);
}

if( --refCount == 0 )
delete this;
}
asILockableSharedBool *GetWeakRefFlag()
{
if( !weakRefFlag )
{
// Lock globally so no other thread can attempt
// to create a shared bool at the same time
asAcquireExclusiveLock();

// Make sure another thread didn't create the
// flag while we waited for the lock
if( !weakRefFlag )
weakRefFlag = asCreateLockableSharedBool();

asReleaseExclusiveLock();
}

return weakRefFlag;
}

static MyClass *Factory() { return new MyClass(); }

protected:
int refCount;
asILockableSharedBool *weakRefFlag;
};


PARTNERS