Here is a standard (not to say recommended) way of implementing Release method of the IUnknown COM interface (directly taken from MSDN):
ULONG CMyMAPIObject::Release()
{
// Decrement the object's internal counter.
ULONG ulRefCount = InterlockedDecrement(m_cRef);
if (0 == m_cRef)
{
delete this;
}
return ulRefCount;
}
I was wondering if a race condition could occur if the apartment model is not STA:
- say there is one reference left
- thread 1 releases it by calling Release
- it runs and is stopped just before
delete this
- thread 2 is scheduled and obtain a new reference to the object, e.g. by calling QueryInterface or AddRef
- thread 1 continue to execute and runs
delete this
- thread 2 is left with an invalid object
For me the only way to ensure consistency would be to create a flag, say deleted, lock the whole critical section, i.e. all the Release method except the return, and set the flag to true.
And in the AddRef and QueryInterface methods check this flag, and if it's set then reject the request for new reference.
What am I missing?
Thanks in advance.