GetInterfaceFromGlobal блокирует вызыьвающий поток
От: Gurevitch  
Дата: 11.09.08 11:14
Оценка:
Всем привет, ситуация следующая:
имеется ком-сервер, в котором находятся 2 кокласса. Каждый из коклассов получает интерфес на свой объект и работает с ним. Цель сервера — создать что-то вроде адаптера описанных выше объектов для уже существующего клиентского интерфейса. В обоих случаях имеет место маршаллинг указателя на соответствующий интерфейс, реализованный посредством GIT. Это вызвано желанием использовать STA и обеспечить корректный доступ к указателю из всех создаваемых потоков в рамках каждого из коклассов. Это предыстория, а теперь суть:

при инициализации клиентского модуля поледовательно создаются инстанции коклассов. Каждый из коклассов при выполнении конструктора создает инстанцию используемого объекта, подписывается на все его события, регистрирует интерфейс в GIT:


IGlobalInterfaceTable * g_pDAGIT; // определен в каждом классе



void MarshalPtr(CComPtr<IXXXX> _obj)
{
    HRESULT hr = CoCreateInstance( CLSID_StdGlobalInterfaceTable, NULL, CLSCTX_INPROC_SERVER, IID_IGlobalInterfaceTable, (void **) &g_pDAGIT );

    hr = g_pDAGIT->RegisterInterfaceInGlobal( static_cast<IXXXX *>(_obj), IID_IXXXX, &dwCookie );
}



Потом каждый кокласс создает поток, в котором инициализируется STA и который призван выполнять методы объявленные в интерфейсе IXXXX. При этом реализация получения интерфейса выглядит так:


CComPtr<IXXX> GetMarshalledPtr()
{
    CComPtr<IXXXX> ret;

    HRESULT hr = CoCreateInstance( CLSID_StdGlobalInterfaceTable, NULL, CLSCTX_INPROC_SERVER, IID_IGlobalInterfaceTable, (void **) &g_pDAGIT );

    hr = g_pDAGIT->GetInterfaceFromGlobal( dwCookie, IID_IXXXX, (void **) &ret );

    g_pDAGIT->Release();

    return ret;
}



Таким образом, так как коклассы инициализируются последовательно, для каждого из них выполняется своя функция MarshalPtr. dwCookie отличается на 1 (видимо это идентификатор в таблице). Далее клиент вызывает одну из функций интерфейса одного из коклассов, в которой происходит вызов функции адаптируемого объекта. Стоит отметить, что все функции интерфейсов коклассов синхронизируются с потоком (в котором выполняются методы адаптируемых объектов) посредством WaitForSIngleObject и событий. Далее, при вызове происходит блокировка вызывающего потока (при выполнении GetInterfaceFromGlobal). Кстати если убрать WaitForSingleObject, то все работает корректно.. Но ведь WaitForSingleObject и GetInterfaceFromGlobal выполняются в разных потоках...Может у GIT есть какие-то специфические особенности?
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.