views:

41

answers:

2

Hi,

I have been reading MSDN articles about COM Threading Model. In one of those (http://msdn.microsoft.com/en-us/library/ms687205%28VS.85%29.aspx), I came across following line: "Like other servers, in-process servers can be single-threaded, apartment-threaded, or free-threaded.".

I am confused about what (COM Client thread and COM Server Object) is put and where..

  • if COM client thread calls CoInitializeEx(COINIT_MULTITHREADED), will object be created in on MTA that may have more than one object and put this thread in it?

  • If CoInitializeEx(NULL), then will it create a new apartment if one does not exists and put this object and thread in it?

  • If client does not call CoInitialize then it would create a "host" thread, create object and place object and thread in it? Is this what the line mentioned above is calls single-threaded?

You can see I am confused!

Any help will be appreciated, Thanks, -Neel.

+2  A: 

That line was designed to create confusion, as near as I can tell.

  • Unlikely, COM servers announce the threading model they support in the registry with the ThreadingModel value. Which is quite often "Apartment" (or missing, same thing). COM will create an STA thread to give it a safe home. Only if it says "Both" or "Free" will the object be created on your thread and no marshaling will be needed.

  • Yes, that creates an STA apartment and the object will live on that thread, regardless of its ThreadingModel.

  • Not calling CoInitialize will make any COM API fail, including attempts to create a COM object.

Hans Passant
A: 

I upvoted Hans' answer, but I also thought maybe I could help to remove some confusion by saying something about apartments. What are they, and why do they exist at all?

A good way to think about an Apartment is "it's a place where COM object instances live". (It is possible actually for some instances to be used simultaneously in different apartments, but it's relatively unusual and you would know if you were doing this - your COM class needs some special work to achieve it). So in general a COM object instance is created in an apartment and it spends its whole life there.

A Single Thread Apartment (STA) is where only one thread can be executing COM instance code at any time. If you're the author of a COM class, this allows you to make some assumptions. In particular it frees you from the burden of protecting your internal data from concurrent accesses. This is especially important if your programming language lacks the features required to do this. I'm thinking of classic VB here. So this was the original kind of apartment, and it's why we mark COM classes that need an STA with the word "Apartment".

Because a COM instance in an STA can only be executed on that STA's thread, things get interesting when you pass a reference (pointer) to that instance over to code that runs on a different thread. If I'm in thread A and I call a method in a COM instance that lives in an STA on thread B, some magic has to happen. The COM runtime steps in, blocks thread A while it schedules some work on thread B for the COM instance to do. It actually uses the Windows message queue to achieve this. The key concept here is interception: COM does some work in-between your caller and your COM instance.

Multiple different COM instances can live in the same apartment, in which case no interception takes place when they call each other.

Sometimes the author makes the choice that he will manage concurrency himself, in order to minimize the overhead of COM interception and in this case he can mark his COM classes as "Free". This means that he cannot rely on the same thread being used each time his COM instance is invoked, and indeed the same instance may be called on multiple threads at the same time.

Marking a COM class as "Both" actually places a greater demand on the COM class author. Like "Free" it means that he cannot expect the same thread to be used for each call to a COM instance, but it also insists that any callbacks from the COM instance out to the calling code will happen on the same thread that invoked the COM instance. This is a necessary restriction if the COM instances are to work correctly in an STA.

To summarize, Apartments were created so that COM class authors could choose how much work they were prepared to do themselves (with regard to concurrency), versus how much to leave to the platform. I think the key to understanding Apartments is to think about the interception that takes place when code in one apartment calls code in another apartment.

Martin