threading in com what is an apartment and why do i care?

Post on 19-Jan-2016

214 Views

Category:

Documents

0 Downloads

Preview:

Click to see full reader

TRANSCRIPT

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

top related