IUnknown.Release标准实现竞争条件?

Pra*_*eek 2 c++ windows com winapi multithreading

以下是实现IUnknown COM接口的Release方法的标准(不推荐)方法(直接取自MSDN):

ULONG CMyMAPIObject::Release()
{
    // Decrement the object's internal counter.
    ULONG ulRefCount = InterlockedDecrement(m_cRef);
    if (0 == m_cRef)
    {
        delete this;
    }
    return ulRefCount;
}
Run Code Online (Sandbox Code Playgroud)

我想知道如果公寓模型不是STA,是否会出现竞争条件:

  • 说剩下一个参考
  • 线程1通过调用Release释放它
  • 它运行并在之前停止 delete this
  • 线程2被调度并获得对该对象的新引用,例如通过调用QueryInterfaceAddRef
  • 线程1继续执行并运行 delete this
  • 线程2留有无效对象

对我来说,确保一致性的唯一方法是创建一个标志,比如删除,锁定整个关键部分,即除了返回之外的所有Release方法,并将标志设置为true.

并在AddRefQueryInterface方法中检查此标志,如果已设置,则拒绝新引用的请求.

我错过了什么?

提前致谢.

Han*_*ant 6

线程2被调度并获得对该对象的新引用,例如通过调用QueryInterface或AddRef

只有当它已经引用了IUnknown或者该对象实现的其他接口之一时,它才能执行此操作.之前进行了AddRef()调用.因此,引用计数永远不会被另一个线程的Release调用减少到小于1的值.

要正确编写代码,必须将ulRefCount与0进行比较,而不是m_cRef.