int process_id == fork();
if (process_id == 0)
exec(«…/bin/serverd»);
Аноним, 1981
В предыдущей главе были представлены основы апартаментов COM и проиллюстрирована COM-архитектура удаленного доступа с изрядным количеством деталей. Были исследованы правила управления ссылками на объекты COM в условиях многопоточной среды, а также методика реализации классов и объектов COM, работающих в потоках. В этой главе будут рассматриваться проблемы, возникающие при управлении процессами и приложениями при использовании COM. Основное внимание будет сосредоточено на том, как апартаменты соотносятся с локализацией ошибок, доверительными отношениями и контекстом защиты.
Подводные камни внутрипроцессной активации
Итак, серверы COM были ранее представлены как внутрипроцессные модули кода, загружаемые в активизирующий их процесс с целью создания объектов и выполнения их методов. Для значительного класса объектов это является разумной стратегией развертывания. Эта стратегия, однако, не лишена недостатков. Одним из подводных камней при запуске объекта в клиентском процессе является отсутствие изоляции ошибок. Если объект вызывает нарушение условий доступа или другую фатальную ошибку во время исполнения, то клиентский процесс завершится вместе с объектом. Более того, если программа клиента вызовет какую-либо ошибку, то все объекты, созданные в его адресном пространстве, будут немедленно уничтожены без предупреждения. Эта проблема также относится к тем клиентам, которые решат осуществить нормальный выход, например, когда конечный пользователь закрывает одно из приложений. Когда клиентский процесс завершается, любые объекты, созданные в адресном пространстве клиента, будут уничтожены, даже если внешние клиенты вне процесса хранят легальные импортированные ссылки. Очевидно, что если клиентский процесс прекратится, то при активизации внутри процесса жизнь объекта может быть прервана преждевременно.
Другая возможная ловушка при выполнении клиентского процесса состоит в совместном использовании контекста защиты. Когда клиент активизирует объект внутри процесса, методы объекта выполняются с использованием мандата ( credential ) защиты клиента. Это означает, что объекты, созданные привилегированными пользователями, могут нанести значительные повреждения. Кроме того, это означает, что объекты, созданные клиентами с относительно меньшей степенью доверия, могут не получить достаточных привилегий для доступа к ресурсам, необходимым для корректного функционирования объекта. К сожалению, нет простого способа обеспечения внутрипроцессного объекта его собственным контекстом защиты.
Еще один подводный камень при внутрипроцессной активации состоит в том, что она не позволяет производить распределенные вычисления. Если объект должен быть активирован в адресном пространстве клиента, то по определению он разделит CPU (central processor unit – центральный процессор) и другие локальные ресурсы с клиентом. Внутрипроцессная активация также делает затруднительным совместное использование одного и того же объекта несколькими клиентскими процессами. Хотя понятие апартамента и допускает экспорт объектных ссылок из любого процесса (включая и те процессы, которые по традиции рассматривались как клиентские), тем не менее, трудно представить себе семантику активации для совместного использования внутрипроцессного экземпляра.
Для решения этих проблем COM допускает активацию классов в отдельных процессах. При активации в отдельном процессе каждый класс (или группа классов) может иметь свой отдельный контекст защиты. Это означает, что разработчик класса сам контролирует, каким пользователям позволено связываться с его объектами. Кроме того, разработчик класса контролирует, какой набор мандатов защиты должен использовать процесс. В зависимости от фактической упаковки класса разработчик класса также управляет тем, когда окружающий процесс закончится (и закончится ли вообще). Наконец, активация класса в отдельном процессе обеспечивает уровень изоляции ошибок, достаточный для изоляции клиента и объектов от завершения в результате ошибок друг друга.
Диспетчер управления COM-сервисами ( Service Control Manager – SCM ) обеспечивает связь между CLSID и серверными процессами в реестре. Это позволяет SCM запускать серверный процесс при поступлении клиентских запросов на активацию. Если предположить, что код для класса будет упакован как образ процесса (ЕХЕ), а не как DLL, то достаточно использовать ключ реестра LocalServer32 вместо InprocServer32 , как показано в следующем примере:
Читать дальше