Всем привет. Может то наступал уже на такие грабли:
Есть некоторый = интерфейс ISomeClass. Потоковая модель — apparment
Объект этого класса может порождать рабочие потоки. Естественно, указетель в рабочий поток проходит через процедуру маршилинга:
// маршалим
CoMarshalInterThreadInterfaceInStream(__uuidof(ISomeClass),
reinterpret_cast<LPUNKNOWN>(this),
&p_stream);
...
Worker::Execute(...)
{
// демаршалим объект в рабочем потоке:
CComPtr<ISomeClass> p_some_class;
hr = ::CoGetInterfaceAndReleaseStream(p_stream, __uuidof(ISomeClass), (void**) &p_some_class);
...
}
Теперь, собственно в чем проблемма :
При уничтожении ISomeClass в методе FinalRelease (я использую ATL) проиходит уничножение пула потоков. Последовательно гасятся все рабочие потоки, но если это просиходит в момент Worker::Execute(...) то получается deadlock, т.к. с одной сотороны объект разрушается в основном потоке, а с другой стороны при выходе из области видимости загшлушки CComPtr<ISomeClass> p_some_class тоже вызывается Release, который так же переадресовывается основному объекту. Соотвественно, рабочий поток, нормальным образом завершится не может.
Мне пока пришла у меня 2 идеи как этого избежать:
1. проставлять какой-нить флаг, в рабочем потоке делать так :
Worker::Execute(...)
{
if (p_some_class.destorying)
{
p_some_class.Detach(); // чтобы избежать вызова Release()
}
}
но так вроде будет лик?
или еще
2. Вариант перекрыть Release для ISomeClass и вызывать остановку рабочих потоков,раньше, но не понятно, когда именно
Что многоуважаемый All думает по этому поводу?
Заранее — благдарю