Время жизни сервера
Время жизни сервера
В предыдущих разделах было показано, как СОМ автоматически загружает DLL с целью перенесения реализации объектов в адресное пространство клиентских программ. Однако пока не обсуждалось, как и когда эти DLL выгружаются. Вообще говоря, серверные DLL могут предотвращать преждевременную выгрузку, но именно клиент выбирает момент, когда DLL фактически перестают использоваться. Клиенты, желающие освободить неиспользуемые DLL, вызывают API-функцию СОМ CoFreeUnusedLibraries:
void CoFreeUnusedLibraries(void);
Обычно эта подпрограмма вызывается клиентами в свободное время с целью собрать мусор в своем адресном пространстве. При вызове CoFreeUnusedLibraries СОМ опрашивает каждую из загруженных DLL, чтобы выявить, какие из них не используются. Это делается посредством вызова в каждой DLL функции DllCanUnloadNow, которая должна быть явно экспортирована из этой динамически подключаемой библиотеки.
Функция DllCanUnloadNow, которую экспортирует DLL каждого сервера, должна соответствовать следующей сигнатуре:
HRESULT DllCanUnloadNow(void);
Если DLL желает быть освобожденной, то она возвращает S_OK. Если DLL хочет остаться загруженной, то она возвращает S_FALSE. Серверные DLL должны оставаться загруженными по крайней мере до тех пор, пока сохраняются интерфейсные указатели на ее объекты. Это означает, что в DLL должен быть счетчик всех существующих ссылок на объекты. Чтобы упростить реализацию этого, большинство DLL содержат одну переменную для счетчика блокировок (lock count) и используют две функции для автоматического инкрементирования и декрементирования этого счетчика:
LONG g_cLocks = 0; void LockModule(void)
{ InterlockedIncrement(&g_cLocks); }
void UnlockModule(void)
{ InterlockedDecrement(&g_cLocks); }
При наличии этих подпрограмм реализация DllCanUnloadNow становится чрезвычайно простой:
STDAPI DllCanUnloadNow(void)
{ return g_cLocks == 0 ? S_OK : S_FALSE; }
Oстается только вызывать в подходящее время подпрограммы LockModule и UnlockModule.
Существуют две основные причины, которые должны оставлять DLL сервера загруженной: внешние ссылки на экземпляры объектов и объекты класса, а также невыполненные вызовы IClassFactory::LockServer. Вполне очевидно, как добавить поддержку DllCanUnloadNow в экземпляры и объекты классов. Объекты, расположенные в динамически распределяемой области памяти (такие, как экземпляры классов) просто инкрементируют счетчик блокировок сервера при первом вызове AddRef:
STDMETHODIMP_(ULONG) Chimp::AddRef(void)
{ if (m_cRef == 0) LockModule(); return InterlockedIncrement(&m_cRef); }
и декрементируют счетчик блокировок при заключительном вызове Release:
STDMETHODIMP_(ULONG) Chimp::Release (void)
{ LONG res = InterlockedDecrement(&m_cRef); if (res == 0)
{ delete this; UnlockModule(); }
return res; }
Поскольку объекты, не размещенные в динамически распределяемой области памяти (такие, как объекты классов), не содержат счетчика ссылок, при каждом вызове AddRef и Release нужно инкрементировать или декрементировать счетчик блокировок:
STDMETHODIMP_(ULONG) ChimpClass::AddRef(void) {
LockModule();
return 2;
}
STDMETHODIMP_(ULONG) ChimpClass::Release (void) {
UnlockModule();
return 1;
}
Объекты классов, которые реализуют IClassFactory, должны устанавливать свои серверные счетчики блокировок на вызовы IClassFactory::LockServer:
STDMETHODIMP ChimpClass::LockServer(BOOL bLock)
{
if (bLock) LockModule();
else UnlockModule();
return S_OK;
}
Как будет обсуждаться в главе 6, IClassFactory::LockServer создана в первую очередь для внепроцессных серверов, но она достаточно проста и для использования во внутрипроцессных серверах.
Следует заметить, что в протоколе CoFreeUnusedLibraries/DllCanUnloadNow неотъемлемо присутствует состояние гонки (race condition). Возможно, что один поток задач будет выполнять заключительное освобождение последнего экземпляра, экспортированного из DLL, в то время как второй поток будет выполнять подпрограмму CoFreeUnusedLibraries. В СОМ приняты все меры предосторожности, чтобы избежать этой ситуации. В частности, в реализацию СОМ под Windows NT 4.0 Service Pack 2 добавлена специальная возможность для борьбы с состоянием гонки. Версия Service Pack 2 библиотеки СОМ определяет, чтобы к DLL обращались из нескольких потоков, и вместо того, чтобы незамедлительно выгружать DLL изнутри CoFreeUnusedLibraries, СОМ ставит DLL в очередь DLL, подлежащих освобождению. Затем СОМ будет ждать неопределенное время, пока не разрешит этим неиспользуемым серверным DLL освободиться посредством последующего вызова CoFreeUnusedLibraries, подтверждающего, что никаких остаточных вызовов Release уже не исполняется[1]. Это означает, что в многопоточных средах выгрузка DLL из своего клиента может осуществляться значительно дольше, чем можно ожидать.
Более 800 000 книг и аудиокниг! 📚
Получи 2 месяца Литрес Подписки в подарок и наслаждайся неограниченным чтением
ПОЛУЧИТЬ ПОДАРОКЧитайте также
Смысл жизни – 2
Смысл жизни – 2 Вам случалось когда-нибудь в теплую летнюю ночь лежать, глядя на звезды, и думать, почему вы живете на свете? Каково ваше место в жизни и как следует жить дальше?Да, вот и мне не случалось.Тем не менее я выработал собственную теорию жизни, Вселенной и всего на
12.14.2 Время жизни (Time-To-Live)
12.14.2 Время жизни (Time-To-Live) В RFC 1035 (специфицирует протокол DNS) заявлено, что TTL в записи SOA — это минимальное значение тайм-аута, разрешенное для всех записей. Но на практике администратору хочется использовать TTL в записи SOA как значение по умолчанию, указывая меньшие значения
Знакомства «для жизни»
Знакомства «для жизни» Люди с Самыми Серьезными Намерениями. Цель поиска – как минимум, хороший и долгоиграющий друг, как максимум – большая любовь на всю оставшуюся жизнь (или хотя бы на ее часть, превышающую 24 часа).Наш выбор – сайты знакомств! И то, как мы увидим ниже,
Время ожидания ответа сервера (Internet Explorer 4.0 SP1 и выше)
Время ожидания ответа сервера (Internet Explorer 4.0 SP1 и выше) При работе в интернете иногда приходится обращаться к весьма удаленным или очень медленным сайтам, в связи с чем у Internet Explorer не всегда хватает терпения дождаться ответа от сервера, и он выдает такие сообщения: "Microsoft Internet
16. Радуюсь жизни…
16. Радуюсь жизни… • Вопрос 44: Поставил НОД Админ Рус 2.51.26 на ноут Gateway (Celeron-300, RAM 64, WinXP SP1), обновил базу до текущей версии. При стартах НОД говорит - не удалось запустить резидентную защиту. Для того, чтобы запустить ее руками, надо подождать минут 5, иначе не запускается.
Время жизни и область действия
Время жизни и область действия Понятия "время жизни" и "область действия" являются очень важными для понимания структуры программ на языке Си. Время жизни переменной может быть либо "глобальным", либо "локальным". Объект с глобальным временем жизни характеризуется тем, что
8. Область видимости и время жизни
8. Область видимости и время жизни В этой главе обсуждаются два важных вопроса, касающиеся объявлений в С++. Где употребляется объявленное имя? Когда можно безопасно использовать объект или вызывать функцию, т.е. каково время жизни сущности в программе? Для ответа на
Радуйся жизни!
Радуйся жизни! А я говорю вам: когда вы трудитесь, вы исполняете часть самой ранней мечты земли, уготованную вам в те времена, когда эта мечта родилась. И работая, вы истинно любите жизнь. А возлюбить жизнь через работу — значит приблизиться к глубочайшей тайне
2.1.3 Время Жизни
2.1.3 Время Жизни Если программист не указал иного, то объект создается, когда встречается его описание, и уничтожается, когда его имя выходит из области видимости, Объекты с глобальными именами создаются и инициализируются один раз (только) и «живут» до завершения
голубятня: Игрой по жизни
голубятня: Игрой по жизни Автор: Сергей ГолубицкийДжем сегодня неожиданный, потому как собираюсь рассказать об одной внешне заурядной компьютерной игре, мимо которой все всегда проходят мимо. Наверное, потому, что хоть и лежит эта игра под самым носом, повернута она к
2.4.2. Время установки Windows 7 и время жизни аккумулятора
2.4.2. Время установки Windows 7 и время жизни аккумулятора Если вы устанавливаете Windows 7 на ноутбук или нетбук, желательно подключить его к сети питания. Если это невозможно, тогда лучше не начинать установку Windows. Хотя весь процесс установки занимает около 20–25 минут (во всяком
Из жизни шпионов
Из жизни шпионов Автор: Киви Берд Уходящие на пенсию шпионы всегда уносят в памяти ворох колоритных историй из того ряда, про который парадоксально говорят «слишком неправдоподобно, чтобы быть вымыслом». К сожалению, далеко не все решаются эти истории рассказывать