
Singletons & 'Interface Marshalled for a different thread' error
Dmitry,
I believe that your problem is in the caching of the interface pointer in
m_pSingleton2. You cannot do that - the proxies are always relative to a
thread and the error that you are getting is notorius for using proxy
created for one thread and used in another. Instead of caching the pointer,
try using the GIT (Global Interface Table) which solves exactly this
problem:
// in your class:
DWORD m_dwSingleton2; // = 0
static IGlobalInterfaceTable *sm_pGIT; // = 0 the
pointer to the GIT CAN BE cached and can be used in ANY thread
// in the registration code:
Singleton1Ptr pSingleton2;
if( 0 == m_dwSingleton2 )
{
pSingleton2.CreateInstance( __uuidof(Singleton2CoClass) );
if( 0 == sm_pGIT )
::CoCreateInstance( CLSID_StdGlobalInterfaceTable, 0,
CLSCTX_INPROC_SERVER, __uuidof(IGlobalInterfaceTable), (void**)&sm_pGIT );
sm_pGIT->RegisterInterfaceInGlobal( pSingleton2, __uuidof(Singleton1),
&m_dwSingleton2 );
Quote:
}
else
sm_pGIT->GetInterfaceFromGlobal( m_dwSingleton2, __uuidof(Singleton1),
(void**)&pSingleton2 );
pSingleton->Register();
// don't forget of course to do somewhere else:
sm_pGIT->Release();
If you are working with VS.NET, there is a class CComGITPtr (I believe),
that does all that for you.
Hope this will help.
Val
Quote:
> Hi,
> Here's the problem:
> There're 2 singletons among other COM objects.
> Singleton1 has a pointer to Singleton2 : Singleton1Ptr m_pSingleton2.
> Singleton1 has to register with Singleton2 on activation and
> unregister on shutdown (Using Register() and Unregister() functions).
> Singleton2 (registrator) creates a thread on creation. This thread
> uses a pointer to the registrator(parent object) and has no idea about
> other interfaces. It doesnt interact with any other objects in any
> apartments.
> Singleton1 doesnt create any threads at all.
> The error appears when Singleton1 tryes to unregister with Singleton2
> on call to Singleton2->Unregister(), which fails with error
> 'marshalled for a different thread'. Registration went fine, i.e.
> Singleton2->Register() didn't return any errors. There's no thread
> involved in these calls!
> Singleton1 object exists while Singleton2 calls to Unregister(),
> however I was not able to step into Singleton2->Unregister() in
> de{*filter*}. It fails before that.
> Both singletons are declared with 'FREE threaded apartment' model.