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




Управление жизненным циклом и маршалинг - часть 9


Для предотвращения этой ситуации регистрационный поток мог бы проверять счетчик блокировок, поддерживаемый объектной реализацией IExternalConnection и осуществлять операцию регистрации только тогда, когда не существует внешних ссылок. Это предполагает, что объект реализует IExternalConnection следующим образом:

class Monitor : public IExternalConnection, public IMonitor { LONG m_cRef; // normal COM reference count // обычный счетчик ссылок СОМ LONG m_cExtRef; // external reference count // счетчик внешних ссылок Monitor(void) : m_cRef(0), m_cExtRef(0) { ... }

STDMETHODIMP_(DWORD) AddConnection(DWORD extconn, DWORD) { if (extconn & EXTCONN_STRONG) // must check for this bit // нужно проверить этот бит return InterlockedIncrement(&m_cExtRef); }

STDMETHODIMP_(DWORD) ReleaseConnection(DWORD extconn, DWORD, BOOL bLastUnlockKillsStub) { DWORD res = 0; if (extconn & EXTCONN_STRONG) { // must check for this bit // нужно проверить этот бит res = InterlockedDecrement(&m_cExtRef); if (res == 0 && bLastUnlockKillsStub) CoDisconnectObject(this, 0); } return res; } } : : : : : : }

Получив эту реализацию, подпрограмма потока могла бы проверить состояние объекта и решить, выполнять или нет операцию регистрации, основываясь на уровне активности объекта:

DWORD WINAPI ThreadProc(void *pv) { // assume ptr to real object is passed to CreateThread // пусть указатель на действительный объект передается в CreateThread

Monitor *pm = (Monitor*)pv; while (1) { // sleep for 10 seconds // ожидаем 10 секунд Sleep(1OOOO); // if object is not in use, perform a log operation // если объект не используется, то выполняем операцию регистрации if (pm->m_cExtRef == 0) pm->TryToLogSampleData(); } return 0; }

Если принять, что метод объекта TryToLogSampleData корректно поддерживает параллелизм, то данная поточная процедура будет регистрировать данные только при условии, что объект не используется внешними клиентами или не осуществляет активный контроль (напомним, что при контроле объект увеличивает счетчик внешних ссылок посредством CoLockObjectExternal).Хотя данный пример может показаться несколько запутанным, имеются случаи, когда отслеживание внешних ссылок является решающим для обеспечения правильности операции. Один классический пример описан в главе 6 и относится к регистрации объектов класса на внепроцессных серверах.

1

В действительности локальный OR ждет в течение короткого промежутка времени, чтобы предоставить шанс демаршализоваться любым оставшимся маршализованным объектным ссылкам, созданным покойным клиентом.




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