Сущность технологии COM



Стандартный маршалинг, потоки и протоколы - часть 3


Отметим, что поскольку окна, подобно объектам на основе STA, обладают потоковой привязкой, WndProc будет выполняться в апартаменте объекта. Чтобы избежать чрезмерного количества переключения потоков, в версии СОМ для Windows 95 предусмотрен транспортный RPC-механизм, который обходит RPC-кэш потоков и вызывает PostMessage из потока вызывающего объекта. Этот перенос возможен только в том случае, если клиент находится на том же хосте, что и объект, поскольку API-функция PostMessage не работает в сети.

Для предотвращения взаимоблокировки все типы апартаментов СОМ поддерживают реентерабельность (повторную входимость). Когда поток в апартаменте делает запрос на объект вне апартамента вызывающего объекта посредством заместителя, то могут обслуживаться и другие поступающие запросы методов, пока поток вызывающего объекта находится в ожидании ORPC-ответа па первый запрос. Без этой поддержки было бы невозможно создавать системы, основанные на совместно работающих объектах. При написании следующего кода предполагалось, что CLSID_Callback является внутрипроцессным сервером, поддерживающим модель вызывающего потока, и что CLSID_Object является классом, сконфигурированным для активации на удаленной машине:

ICallback *pcb = 0; HRESULT hr = CoCreateInstance(CLSID_Callback, 0, CLSCTX_ALL, IID_ICallback, (void**)&pcb); assert(SUCCEEDED(hr)); // callback object lives in this apt. // объект обратного вызова живет в этом апартаменте I0bject "po = 0; hr = CoCreateInstance(CLSID_Object, 0, CLSCTX_REMOTE_SERVER, IID_Iobject, (void **)&po); assert(SUCCEEDED(hr)); // object lives in different apt. // объект живет в другом апартаменте // make a call to remote object, marshaling a reference to // the callback object as an [in] parameter // делаем вызов удаленного объекта, маршалируя ссылку // на объект обратного вызова как на [in]-параметр hr = po->UseCallback(pcb); // clean up resources // очищаем ресурсы pcb->Release(); pco->Release();

На рис. 5.6 показано, что если апартамент вызывающего объекта не поддерживает реентерабельность, то следующая реализация метода UseCallback вызовет взаимоблокировку:




Содержание  Назад  Вперед