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


         

FTM занимает не менее 16


FTM занимает не менее 16 байт памяти. Поскольку многие внутрипроцессные объекты никогда не используются за пределами своего апартамента, то предварительное выделение памяти для FTM не является лучшим использованием имеющихся ресурсов. В высшей степени вероятно, что объект уже имеет некий примитив для синхронизации потоков. В таком случае FTM может быть отложенно агрегирован (lazy-aggregated) при первом же запросе QueryInterface о IMarshal. Для того чтобы добиться этого, рассмотрим такое определение класса:

class LazyPoint : public IPoint { LONG m_cRef; IUnknown *m_pUnkFTM; long m_x; long m_y; LazyPoint (void) : m_cRef (0) .m_pUnkFTM(0),m_x(0), m_y(0) {} virtual ~LazyPoint(void) { if (m_pUnkFTM) m_pUnkFTM->Release(); } void Lock(void); // acquire object-specific lock // запрашиваем блокировку, специфическую для объектов void Unlock(void); // release object-specific lock // освобождаем блокировку, специфическую для объектов : : : };

Основываясь на таком определении класса, следующая реализация QueryInterface осуществит корректное агрегирование FTM по требованию:

STDMETHODIMP Point::QueryInterface(REFIID riid, void **ppv) { if (riid == IID_IUnknown riid == IID_IPoint) *ppv = static_cast<IPoint*>(this); else if (riid == IID_IMarshal) { this->Lock(); HRESULT hr = E_NOINTERFACE; *ppv = 0; if (m_pUnkFTM == 0) // acquire FTM first time through // получаем первый FTM CoCreateFreeThreadedMarshaler(this, &m_pUnkFTM); if (m_pUnkFTM != 0) // by here, FTM is acquired // здесь получен FTM hr = m_pUnkFTM->QueryInterface(riid, ppv); this->Unlock(); return hr; } else return (*ppv = 0), E_NOINTERFACE; ((IUnknown *)*ppv)->AddRef(); return S_OK; }

Недостатком данного подхода является то, что все запросы QueryInterface на IMarshal будут сериализованы (преобразованы в последовательную форму); тем не менее, если IMarshal вообще не будет запрошен, то будет запрошено меньше ресурсов.

Теперь, когда мы убедились в относительной простоте использования FTM, интересно обсудить случаи, в которых FTM не годится.

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