Доступ к объекту по-прежнему синхронизован, но вызов
SomeMethod(); происходит вне критической секции. Победа? Почти. Осталась одна
маленькая деталь. Давайте посмотрим, что происходит в Proc2():
void Proc2(IObject *pNewObject)
{
m_lockObject.Lock();
if (m_pObject.p)
m_pObject.p->Release();
m_pObject.p = pNewobject;
if (m_pObject.p)
m_pObject.p->AddRef();
m_lockObject.Unlock();
}
|
Очевидно, что вызовы m_pObject.p->AddRef(); и
m_pObject.p->Release(); происходят внутри критической секции. И если вызов
метода AddRef(), как правило, безвреден, то вызов метода Release() может
оказаться последним вызовом Release(), и объект самоуничтожится. В методе
FinalRelease() объекта №2 может быть все что угодно, например, освобождение
объектов, живущих в других подразделениях. А это опять приведет к переключению
ниток и может вызвать самоблокировку объекта №1 по уже известному сценарию.
Придется воспользоваться той же техникой, что и в методе Proc1():
Листинг 13