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;
}
アパートメント モデルがSTAでない場合、競合状態が発生する可能性があるかどうか疑問に思っていました。
- 参照が1つ残っていると言う
- スレッド 1 は、 Releaseを呼び出してそれを解放します
- 実行し、直前に停止します
delete this
- スレッド 2 がスケジュールされ、たとえばQueryInterfaceまたはAddRefを呼び出して、オブジェクトへの新しい参照を取得します。
- スレッド 1 は引き続き実行され、実行されます
delete this
- スレッド 2 には無効なオブジェクトが残っています
私にとって、一貫性を確保する唯一の方法は、deletedなどのフラグを作成し、クリティカル セクション全体、つまりreturn を除くすべてのReleaseメソッドをロックし、フラグをtrueに設定することです。
AddRefメソッドとQueryInterfaceメソッドでこのフラグをチェックし、設定されている場合は、新しい参照のリクエストを拒否します。
私は何が欠けていますか?
前もって感謝します。