Upload
calvin-oliver
View
214
Download
0
Tags:
Embed Size (px)
Citation preview
Threading in COM
What is an Apartment and Why Do I Care?
What is an Apartment
An execution context Contains at least one thread Contains at least one COM object (to be useful) Can contain other restrictions (COM+ contexts)
Types of Apartments Multi-Threaded Apartment (MTA) Single-Thread Apartment (STA) MAIN STA Thread Neutral Apartment (TNA)
How does code call methods
Thread is executing some other code COM object offers some useful method Thread calls that method
Sets up a stack frame Changes IP to the beginning of the method
Very simple; very efficient The thread and the object must be in the
same apartment.
Threads create apartments
Any thread that wants to use COM must call CoInitialize or CoInitializeEx
The COINIT parameter to CoInitializeEx determines the apartment type COINIT_APARTMENTTHREADED = STA COINIT_MULTITHREADED = MTA (will join
existing) CoInitialize legacy method calls Ex version
with COINIT_APARTMENTTHREADED
Apartment model of a process
Process at startup
COM process with apartments
Adding COM objects
COM threads create COM objects CoCreateInstance or CoCreateInstanceEx myObject->get_Application()
Cardinal rule is, “Create the object in the same apartment as the creator thread.”
Apartments are an example of a COM interceptor Checks to see if the object is compatible Creates new threads/apartments as needed
After first CoInitialize call
Sometime later…
We have created new threads that called CoInitializeEx(0, COINIT_MULTITHREADED);
Some of these COM threads have created COM objects For now, we assume the cardinal rule Next we will look at apartment interception
Now our process looks something like this…
Multiple apartment process
Why all the bother?
COM servers and client may be written by completely different groups
When a COM client (written by Company A) calls a COM object (written by Company B)… Is this COM object compatible with this client? More specifically, is the threading model of the
object compatible with the execution environment (apartment) of the thread?
Bottom line, is the COM object thread-safe?
Two threads calling…
Incompatible thread & object
What if the creating thread is in the MTA but the COM object is not thread-safe
Where do we put the new object? Can’t put it in the MTA – other threads may call Can’t put it in an STA – the creating thread can’t
call Enter marshalling
Types of marshalling
Remote machine Call a method of an object on another computer Uses underlying networking – RPC by default
Out of process Call a method of an object that lives in another process on
the same machine Uses IPC – LRPC by default
Cross-apartment within a process Our problem here Uses Windows message queues by default
Cross-apartment COM calls
Apartment interception
Threading models None (Single) – legacy (Main STA) Apartment – Always create in an STA Free – Always create in the MTA Both – Always create in the apartment of the creator thread Neutral – More on this one later
Applies only to DLL, in-process COM server Only problem when the thread calling the method and the
thread executing the method can be the same thread.
COM threading models
Free-Threaded Marshaler
FTM is an aggregated, special IMarshal interface If a COM objects exposes the FTM, it can be
called directly by any thread in the same process. Aggregate the FTM by calling
CoCreateFreeThreadedMarshaler When the interface is marshaled into the calling
apartment, a bogus proxy is created that is a direct pointer to the real interface.
Thread Neutral Apartment
TNA is a “special” STA Max one per process; No thread “lives” in the
TNA Only one thread at a time can be “in” the
apartment. Objects in the apartment are intrinsically thread-
safe. A thread “enters” the apartment, makes its calls
on the objects there, and then leaves. Other threads must wait until the apartment is
empty.
Process with TNA
Threading in .EXE servers
No automatic apartment interception Object will be created in the apartment of its
creator thread Threads still declare their apartments when
calling CoInitializeEx It is your responsibility that an MTA thread does
not create a non-thread-safe object It is your responsibility that the objects are
created in the most efficient apartment
Additional Resources
Essential COM, Don Box Chapter 5 covers In-Proc COM servers Chapter 6 covers Standalone COM servers
Professional ATL COM Programming, Dr. Richard Grimes Chapter 7 covers both types of servers Note the discussion on “Single” vs “Apartment”
MSDN – Search for STA, MTA, TNA, FTM Good articles from Don Box’s “House of COM”
Questions