interface IExternalConnection : IUnknown {
DWORD AddConnection(
[in] DWORD extconn,
// type of reference
// тип ссылки
[in] DWORD reserved
// reserved, must be zero
// зарезервировано, должно быть равно нулю
);
DWORD ReleaseConnection(
[in] DWORD extconn,
// type of reference
// тип ссылки
[in] DWORD reserved,
// reserved, must be zero
// зарезервировано, должно быть равно нулю
[in] BOOL fLastReleaseCloses
// should kill stub?
// нужно ли убить заглушку?
); }
При первом подсоединении администратора заглушек к объекту он спрашивает объект, желает ли тот, чтобы его уведомляли о создании или уничтожении внешних ссылок. Он делает это посредством запроса интерфейса
Ожидается, что в объектах, которые реализуют
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; }
Если принять, что метод объекта