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




Снова о времени жизни сервера - часть 5


Этому положению способствовало присутствие метода LockServer в интерфейсе IClassFactory, который внушает разработчикам мысль, что клиенты будто бы способны в действительности обеспечить выполнение сервера. В то время как большинство разработчиков серверов успешно запирают модуль в методах LockServer, для клиента не существовало надежного способа вызвать данный метод. Рассмотрим следующий клиентский код:

IClassFactory *pcf = 0;

HRESULT hr = CoGetClassObject(CLSID_You, CLSCTX_LOCAL_SERVER, О, IID_IClassFactory, (void**)&pcf); if (SUCCEEDED(hr)) hr = pcf->LockServer(TRUE); // keep server running? // поддерживать выполнение сервера?

В первых версиях COM этот фрагмент кода находился бы в условиях серьезной гонки. Отметим, что существует интервал между вызовами CoGetClassObject и IClassFactory::LockServer. В течение этого периода времени другие клиенты могут уничтожить последний остающийся экземпляр класса. Поскольку неосвобожденная ссылка на объект класса игнорируется наивными реализациями серверов, серверный процесс прекратит работу раньше исходного вызова клиентом метода LockServer. Теоретически это можно было бы преодолеть следующим образом:

IClassFactory *pcf = 0; HRESULT hr = S_OK; do { if (pcf) pcf->Release(); hr = CoGetClassObject(CLSID_You, CLSCTX_LOCAL_SERVER, 0, IID_IClassFactory, (void**)&pcf); if (FAILED(hr)) break; hr = pcf->LockServer(TRUE); // keep server running? // поддерживать выполнение сервера? } while (FAILED(hr));

Отметим, что данный фрагмент кода периодически пытается подсоединиться к объекту класса и заблокировать его, пока вызов LockServer проходит успешно. Если сервер завершит работу преждевременно — между вызовами CoGetClassObject и LockServer, то вызов LockServer возвратит сообщение об ошибке, извещающее об отсоединенном заместителе, что вызовет повтор последовательности. Под Windows NT 3.51 и в более ранних версиях этот нелепый код был единственным надежным способом получения ссылки на объект класса.

Был признан тот факт, что многие реализации серверов не использовали IExternalConnection для должного управления временем жизни сервера, и в версии COM под Windows NT 4.0 введена следующая модернизация для замены этих наивных реализаций.


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