Singletons & 'Interface Marshalled for a different thread' error 
Author Message
 Singletons & 'Interface Marshalled for a different thread' error

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.



Sat, 19 Nov 2005 05:44:52 GMT  
 Singletons & 'Interface Marshalled for a different thread' error
Do you have an in-proc (DLL) server or an out-of-proc (EXE) server?

Singleton1Ptr m_pSingleton2;
This naming convention is pretty confusing - how come a pointer of type
Singleton1 is named Singleton2? Who has a pointer to whom? How does this
pointer get its value?

When and how do your singleton instances get created? When and how do
they register with each other? When do they decide to unregister?
--
With best wishes,
    Igor Tandetnik

"For every complex problem, there is a solution that is simple, neat,
and wrong." H.L. Mencken


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.



Sat, 19 Nov 2005 06:26:44 GMT  
 Singletons & 'Interface Marshalled for a different thread' error
If your objects implemented in the out-of-proc server, check
_ATL_XXX_THREADED (XXX should be FREE not APARTMENT) macro in your stdafx.h
file. If you have in-proc server check threading model that client EXE
specified.


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.



Sat, 19 Nov 2005 07:00:08 GMT  
 Singletons & 'Interface Marshalled for a different thread' error
Thanks for responce, guys!
Some more details:


Quote:
> If your objects implemented in the out-of-proc server, check
> _ATL_XXX_THREADED (XXX should be FREE not APARTMENT) macro in your stdafx.h
> file. If you have in-proc server check threading model that client EXE
> specified.

Both of them have :
[
        coclass,
        threading("free"),
        ....
]

in stdafx.h both have
#define _ATL_FREE_THREADED

This marshalling error occurs as I run both as in in-process and
out-of_process servrs.

------------------------------------

Singleton2 (registrator) is created like this in
Singleton1::FinalConstruct():

#import "Singleton2.dll"
....
IXpSingleton2Ptr m_pSingleton2;
...
Singleton1::FinalConstruct()
{
 HRESULT _hr = m_pSingleton2.CreateInstance(__uuidof(CSingleton2));
 m_pSingleton2->Register(...);
 ...

Quote:
}

...and DOESN'T produce any errors! The error occurs when trying
unregister.
Before the application shuts down, Singleton1 is being told to release
all resources by another component. So, when this happens, Singleton1
has to call m_pSingleton2->Unregister().

Singleton1::Stop()
{
 ...
 m_pSingleton2->Unregister();

Quote:
}

That's where the problems comes out..


Sat, 19 Nov 2005 22:01:30 GMT  
 Singletons & 'Interface Marshalled for a different thread' error

Quote:
> Both of them have :
> [
> coclass,
> threading("free"),
>         ....
> ]

> in stdafx.h both have
> #define _ATL_FREE_THREADED

> This marshalling error occurs as I run both as in in-process and
> out-of_process servrs.

> #import "Singleton2.dll"

I see that Singleton2 is implemented in a DLL. Is Singleton1 also
implemented in a DLL, or in an EXE? If the former, is it the same DLL as
the one of Singleton2? Who's loading these DLLs - it's an EXE server,
right? What threading model does this server have?

How is Singleton1 created? When and how is Stop() method called on it?
--
With best wishes,
    Igor Tandetnik

"For every complex problem, there is a solution that is simple, neat,
and wrong." H.L. Mencken



Sat, 19 Nov 2005 22:17:29 GMT  
 Singletons & 'Interface Marshalled for a different thread' error

Quote:
> I see that Singleton2 is implemented in a DLL. Is Singleton1 also
> implemented in a DLL, or in an EXE?

All objects are in DLLs.

 If the former, is it the same DLL as

Quote:
> the one of Singleton2?

different. When out-of-process, also in different Applications.

Quote:
> Who's loading these DLLs - it's an EXE server,
> right? What threading model does this server have?

#define _ATL_FREE_THREADED

Quote:
> How is Singleton1 created? When and how is Stop() method called on it?

By the host process.
There's a service, which creates Singleton1 on Start().
It shuts Singleton1 down on Stop(), basicly delegating the call down
to Singleton1 and other components.
Singleton2 is not controlled by this service. It exists while there's
at least one reference to it from other components.


Sun, 20 Nov 2005 05:22:45 GMT  
 Singletons & 'Interface Marshalled for a different thread' error

Quote:
> > How is Singleton1 created? When and how is Stop() method called on
it?
> By the host process.
> There's a service, which creates Singleton1 on Start().
> It shuts Singleton1 down on Stop(), basicly delegating the call down
> to Singleton1 and other components.
> Singleton2 is not controlled by this service. It exists while there's
> at least one reference to it from other components.

I'm not really familiar with service architecture. Most likely, Start()
and Stop() are called on different threads (confirm with
GetCurrentThreadId). Those threads either initialize COM differently, or
one of them fails to initialize it at all.

I seem to remember a bug in ATL3 Service wizard being mentioned, whereby
the wizard generates CoInitialize(0) call even though a free-threaded
server is requested. Try to figure out exactly how all your threads
initialize COM.
--
With best wishes,
    Igor Tandetnik

"For every complex problem, there is a solution that is simple, neat,
and wrong." H.L. Mencken



Sun, 20 Nov 2005 05:32:44 GMT  
 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.



Sun, 20 Nov 2005 05:59:17 GMT  
 Singletons & 'Interface Marshalled for a different thread' error
GIT did help!
thanks!


Mon, 21 Nov 2005 02:06:38 GMT  
 
 [ 9 post ] 

 Relevant Pages 

1. Create one singleton object in other interface's method (in one project)

2. Error -2147417842 (8001010E) The application called an interface that was marshalled for a different thread.

3. can't call interface in thread

4. can't unmarshal interface in thread

5. A question about '&&'

6. Same EVC + Different PC's = arm exe DIFFERENT file size (iPAQ)

7. how to changed ad's user's password with csharp (different server)

8. How To Get an 'X'-Point Font To Display Correctly On Different Resolutions

9. error PRJ0003: Error spawning 'cl.exe'.

10. 0x8001010E : The application called an interface that was marshalled for a different thread.

11. error C2061: syntax error : identifier 'DBPROPSET'

12. Link error: 'Internal error during ReadSymbolTable'

 

 
Powered by phpBB® Forum Software