Two basic questions about function invocation from STA to MTA.
1.
In my understaning, the owning thread of STA should not touch MTA component, and also in MTA there is no message queue for MTA owning thread to pumping messages.
My question is, if the owning thread of STA calls MTA component (by interface pointer), which thead is responsible for executing in MTA? From my above analysis, seems both STA owner thread (can not touch MTA component) and MTA owner thread (can not receive calls from STA through message queue, snice no message queue in MTA.)
2.
Before function call returns from MTA, will STA thread waiting or it could execute in asynchronous way?
thanks in advance,
George
Arjay
March 30th, 2008, 08:08 PM
Ah COM - you gotta love it.
It's been awhile since I've done any COM, but if I recall for an answer to 1 you can call a MTA object (via a pointer) from a STA. For 2), it depends on how the MTA object has been written. The STA will block if the method call on the MTA is synchronous; it will not block if the MTA object has been written asynchronously and uses a callback event to notify the caller that the operation has finished. Synchronous/Asynchronous functionality really has nothing to do with STA or MTA.
George2
March 31st, 2008, 01:05 AM
Thanks Arjay,
For (2), your reply is clear. For (1), who is responsible for executing in MTA? It should not be the STA owner thread, right?
Ah COM - you gotta love it.
It's been awhile since I've done any COM, but if I recall for an answer to 1 you can call a MTA object (via a pointer) from a STA. For 2), it depends on how the MTA object has been written. The STA will block if the method call on the MTA is synchronous; it will not block if the MTA object has been written asynchronously and uses a callback event to notify the caller that the operation has finished. Synchronous/Asynchronous functionality really has nothing to do with STA or MTA.
regards,
George
Arjay
March 31st, 2008, 01:29 AM
From what I recall, you can create an MTA object from within an STA; however, method calls use the message queue rather than rpc.
George2
March 31st, 2008, 02:46 AM
Hi Arjay,
1.
I think when you create MTA object from STA thread, it will not be in current STA thread. Right?
2.
Since STA has its own message queue to receive method call from other apartment. Method call from STA to outside apartment, will resue the message queue or use separate message queue?
From what I recall, you can create an MTA object from within an STA; however, method calls use the message queue rather than rpc.
regards,
George
Igor Vartanov
March 31st, 2008, 08:19 AM
1.
I think when you create MTA object from STA thread, it will not be in current STA thread. Right?Well, I can feel some strange flavour in this questioning. An apartment (STA or MTA) belongs with a client side, and an object may be created anywhere (elsewhere) depending on COM server settings. So I hardly can see any sense in this particular question.
2.
Since STA has its own message queue to receive method call from other apartment. Method call from STA to outside apartment, will resue the message queue or use separate message queue?A STA message queue role is to serialize calls to interfaces/objects disregarding the fact if interface gets called directly or via proxy, or if it in-proc or remote. Each and every call to an interface method will pass the apartment message queue. And I scarcely can understand what "separate message queue" might be talked about in the context.
Arjay
March 31st, 2008, 08:25 AM
Is the question whether you can create and use an MTA object in an STA thread, if so I believe the answer is yes. But, then again I haven't done much COM since 2002.
Check out this CodeGuru article, "A Simple Example To Explain COM STA, MTA, and Auto-threaded Modules (http://www.codeguru.com/cpp/com-tech/activex/apts/article.php/c5551/)".
George2
March 31st, 2008, 08:53 AM
Thanks Arjay,
1.
My point is not in an STA, we can not create an MTA object instance. I mean if we create an MTA object instance, the object instance will be in an MTA created by COM Runtime, other than in the STA itself, agree?
2.
The referred article is very cool! I think the search engine of CodeGuru is much better than that of Google. :-)
Is the question whether you can create and use an MTA object in an STA thread, if so I believe the answer is yes. But, then again I haven't done much COM since 2002.
Check out this CodeGuru article, "A Simple Example To Explain COM STA, MTA, and Auto-threaded Modules (http://www.codeguru.com/cpp/com-tech/activex/apts/article.php/c5551/)".
regards,
George
George2
March 31st, 2008, 08:57 AM
Thanks Igor,
Sorry my English description is bad. :-)
1.
Well, I can feel some strange flavour in this questioning. An apartment (STA or MTA) belongs with a client side, and an object may be created anywhere (elsewhere) depending on COM server settings. So I hardly can see any sense in this particular question.
My point is not in an STA, we can not create an MTA object instance. I mean if we create an MTA object instance, the object instance will be in an MTA created by COM Runtime, other than in the STA itself, agree?
2.
A STA message queue role is to serialize calls to interfaces/objects disregarding the fact if interface gets called directly or via proxy, or if it in-proc or remote. Each and every call to an interface method will pass the apartment message queue. And I scarcely can understand what "separate message queue" might be talked about in the context.
I mean the message queue of a STA, is only responsible for receiving in-coming method call and for receiving return result from other apartment.
For out-going method call of the current STA to other apartment (either STA or MTA), the message queue of the current STA will not be used (used I mean putting the out-going method call parameters into the message queue), right?
regards,
George
Arjay
March 31st, 2008, 09:26 AM
I think the search engine of CodeGuru is much better than that of Google. :-) Your welcome. P.S. I used Google with the phrase "STA MTA Object". The link I gave you showed up as the first hit.
George2
March 31st, 2008, 09:49 AM
Cool, Arjay!
Do you have answer to my question item 1 in post #8? If no answer now, I will study the link you recommended, it looks really cool!
Your welcome. P.S. I used Google with the phrase "STA MTA Object". The link I gave you showed up as the first hit.
regards,
George
Arjay
March 31st, 2008, 10:24 AM
Do you have answer to my question item 1 in post #8?Sorry, no. It's been too long for me. Read up on it and create a few test COM objects and try it out.
Igor Vartanov
March 31st, 2008, 01:50 PM
I got your point at last! :D
Sorry my English description is bad. :-)Never mind, my understanding of English hardly could be called perfect. :D
1.
My point is not in an STA, we can not create an MTA object instance. I mean if we create an MTA object instance, the object instance will be in an MTA created by COM Runtime, other than in the STA itself, agree?Please be consistent in terminology. When you talk about apartments, please talk about client apartment and server apartment. In case your client apartment is STA, and server apartment is MTA, disregarding the fact that even your server is in-proc one, COM cannot create a different-type server instance in context of a thread that already belongs to initial STA. On this reason COM creates another thread for MTA server. In case both client and server apartments match in types, COM uses the same thread (and apartment correspondingly) for client and server.
2.
I mean the message queue of a STA, is only responsible for receiving in-coming method call and for receiving return result from other apartment.
For out-going method call of the current STA to other apartment (either STA or MTA), the message queue of the current STA will not be used (used I mean putting the out-going method call parameters into the message queue), right?Right.
George2
April 1st, 2008, 12:29 AM
Thanks all the same, Arjay!
Sorry, no. It's been too long for me. Read up on it and create a few test COM objects and try it out.
regards,
George
George2
April 1st, 2008, 01:25 AM
Thanks Igor,
Two more questions. :-)
1.
A call from STA to another STA, since STA owner thread can not touch other apartment, when STA calls another component in another STA, I am confused who is responsible for delivering the method call information (e.g. parameters) to another STA's message queue?
I think the process is like this from my study, STA will push its method call parameter and other information into a COM Runtime message queue owned by COM Runtime, then COM Runtime thread is responsible to retrieve message from the COM Runtime message queue and deliver it to the destination STA.
Am I correct?
2.
If (1) is correct, how does the destination STA returns the result to the source STA? I think it should also put the return result information into the COM Runtime message queue and the COM Runtime thread is responsible for sending back the information to the source STA's message queue, right?
I got your point at last! :D
Never mind, my understanding of English hardly could be called perfect. :D
Please be consistent in terminology. When you talk about apartments, please talk about client apartment and server apartment. In case your client apartment is STA, and server apartment is MTA, disregarding the fact that even your server is in-proc one, COM cannot create a different-type server instance in context of a thread that already belongs to initial STA. On this reason COM creates another thread for MTA server. In case both client and server apartments match in types, COM uses the same thread (and apartment correspondingly) for client and server.
Right.
regards,
George
Igor Vartanov
April 2nd, 2008, 06:37 AM
A call from STA to another STA, since STA owner thread can not touch other apartment, when STA calls another component in another STA, I am confused who is responsible for delivering the method call information (e.g. parameters) to another STA's message queue?Calling an interface method results in involving COM runtime in client STA. The COM finds out whether the destination STA is the same or not. And if not, it marshals the method parameters to server STA. In server STA the method call along with (marshaled) parameters are transformed into a message post - and the message gets placed into a STA message queue.
Message pump extracts the message and performs an actual method call in server's STA.
After returning from call a HRESULT is passed back to client STA by the COM runtime.
George2
April 2nd, 2008, 07:30 AM
Thanks Igor,
I want to expand "by the COM runtime", to see how COM Runtime involves in the process of STA call STA.
I think a COM Runtime thread should be created and responsible to be notified by source STA, delivering method call information to destination message queue of destination STA, and the COM Runtime thread is also responsible for receiving result from destination STA (notified by destination STA) to the message queue of source STA.
My understanding correct?
Calling an interface method results in involving COM runtime in client STA. The COM finds out whether the destination STA is the same or not. And if not, it marshals the method parameters to server STA. In server STA the method call along with (marshaled) parameters are transformed into a message post - and the message gets placed into a STA message queue.
Message pump extracts the message and performs an actual method call in server's STA.
After returning from call a HRESULT is passed back to client STA by the COM runtime.
regards,
George
Igor Vartanov
April 2nd, 2008, 11:30 AM
My understanding correct?
Replace "COM Runtime thread" to "COM Runtime" or "COM core", and it will be . :)
I still do not understand why that "thread" steadily gets involved into your analysis. The separate thread could be or could be not created while COM creates server object. In case client initialized STA, and server object is also requiring for STA, the client's apartment will be used for the server object, and therefore, server object will be created in the same thread context. Is it clear? The same thing is with MTAs. The point is apartment type matching. :)
George, typically I investigate such kind of things by means of simplest sample: you create STA server and make it method to report the thread id, and create a client app that also reports its thread id. In case both server and client report the same thread id, you may be absolutely sure they reside in the same apartment. Well, does this sound reasonable for you?
George2
April 3rd, 2008, 05:54 AM
Thanks Igor,
I can understand your points. But I am sorry I have not made myself understood. You describes internal STA operation (function call), but what I describe is cross-STA operation.
Let me clarify my question and why I can not debug in the way you suggested below.
1. You create STA thread T1 and in T1 you create a component C1;
2. You create STA thread T2 and in T2 you create a component C2;
3. You retrieve interface pointer of C2 in thread C1/T1, and you call method of C2 in C1/T1;
In the above scenario, I mean,
I think a COM Runtime thread should be created and responsible to be notified by source STA (T1 + C1), delivering method call information to destination message queue of destination STA (T2 + C2), and the COM Runtime thread is also responsible for receiving result from destination STA (notified by destination STA) to the message queue of source STA.
I make the above conclusion because I think in COM apartment rules, a owner thread in one STA, can not touch the other STA, so in order to deliver message, there should be an intermediate thread by COM Runtime?
My understanding correct?
Replace "COM Runtime thread" to "COM Runtime" or "COM core", and it will be . :)
I still do not understand why that "thread" steadily gets involved into your analysis. The separate thread could be or could be not created while COM creates server object. In case client initialized STA, and server object is also requiring for STA, the client's apartment will be used for the server object, and therefore, server object will be created in the same thread context. Is it clear? The same thing is with MTAs. The point is apartment type matching. :)
George, typically I investigate such kind of things by means of simplest sample: you create STA server and make it method to report the thread id, and create a client app that also reports its thread id. In case both server and client report the same thread id, you may be absolutely sure they reside in the same apartment. Well, does this sound reasonable for you?
regards,
George
Arjay
April 3rd, 2008, 10:47 AM
I've always payed less attention to what threads the COM subsystem create for me, and focused on the bottom line: i.e., what must I do in order to call components from different threads.
For MTA components I don't have to worry about this - I can just pass a pointer from any component to any thread and use the component.
For STA components, if I want to use them outside the compartment I've created them in, I need to marshal the pointer using CoMarshalInterThreadInterfaceInStream (http://msdn2.microsoft.com/en-us/library/ms693316(VS.85).aspx). As far as knowing when to marshall, COM will throw an error telling you that you are trying to access the STA pointer from the wrong thread.
George2
April 3rd, 2008, 11:03 AM
Thanks Arjay,
I totally agree with you. Now I am just interested in how COM Runtime works internally. Any ideas or comments to my post #19?
I've always payed less attention to what threads the COM subsystem create for me, and focused on the bottom line: i.e., what must I do in order to call components from different threads.
For MTA components I don't have to worry about this - I can just pass a pointer from any component to any thread and use the component.
For STA components, if I want to use them outside the compartment I've created them in, I need to marshal the pointer using CoMarshalInterThreadInterfaceInStream (http://msdn2.microsoft.com/en-us/library/ms693316(VS.85).aspx). As far as knowing when to marshall, COM will throw an error telling you that you are trying to access the STA pointer from the wrong thread.
regards,
George
Igor Vartanov
April 3rd, 2008, 12:28 PM
Thanks Igor,
I can understand your points. But I am sorry I have not made myself understood. You describes internal STA operation (function call), but what I describe is cross-STA operation.
Let me clarify my question and why I can not debug in the way you suggested below.
1. You create STA thread T1 and in T1 you create a component C1;
2. You create STA thread T2 and in T2 you create a component C2;
3. You retrieve interface pointer of C2 in thread C1/T1, and you call method of C2 in C1/T1;
In the above scenario, I mean,
I think a COM Runtime thread should be created and responsible to be notified by source STA (T1 + C1), delivering method call information to destination message queue of destination STA (T2 + C2), and the COM Runtime thread is also responsible for receiving result from destination STA (notified by destination STA) to the message queue of source STA.
I make the above conclusion because I think in COM apartment rules, a owner thread in one STA, can not touch the other STA, so in order to deliver message, there should be an intermediate thread by COM Runtime?
My understanding correct?
No it is not. Absolutely not. Every STA is bound to a thread, and exactly that thread is associated with the apartment's message queue we're talking about. So there would be no other additional thread involved in STA-to-STA communucation process. There is no COM runtime thread at all, thre are only threads associated with corresponding apartments, MTA or STA.
George2
April 4th, 2008, 03:31 AM
Thanks Igor,
1.
So, you mean if inside on STA thread (say T1), we call the component from another STA thread (sat T2), T1 will insert the message of method call information into the message queue of hidden window of destination STA (where T2 belongs) directly?
(No COM Runtime thread involved?)
2.
Do you have any reference turorials or code to prove your conclusion in (1)? :-)
No it is not. Absolutely not. Every STA is bound to a thread, and exactly that thread is associated with the apartment's message queue we're talking about. So there would be no other additional thread involved in STA-to-STA communucation process. There is no COM runtime thread at all, thre are only threads associated with corresponding apartments, MTA or STA.
regards,
George
Igor Vartanov
April 4th, 2008, 05:24 AM
1.
So, you mean if inside on STA thread (say T1), we call the component from another STA thread (sat T2), T1 will insert the message of method call information into the message queue of hidden window of destination STA (where T2 belongs) directly?
(No COM Runtime thread involved?)Well, not directly (again, I do not understand your terminology). Crossing apartment boundaries results in involving marshaling mechanism. And the one takes care about placing the message into target apartment's message queue.
The citation from Understanding and Using COM Threading Models (http://msdn2.microsoft.com/en-us/library/ms809971.aspx)
Rather than using thread synchronization objects (mutexes, semaphores, and so forth) to control access to an object by several threads, the marshaling process for STAs translates the call into a WM_USER message and posts the result to a hidden top-level window associated with the apartment when it was created. Calls from several different threads are converted and sent to wait in the apartment's message queue until they are retrieved, dispatched, and executed on the apartment's thread. This process controls access to an apartment's objects by forcing incoming calls to pass through a sort of turnstile, thereby rendering the object's interface implementations thread-safe. An additional benefit of using the message queue is that inter-apartment COM calls are synchronized with window messages, which provides a means for objects that interact with users to synchronize incoming COM calls with the operation of the user interface (UI).
2.
Do you have any reference turorials or code to prove your conclusion in (1)? :-)Afraid, you have to either take my word or find your proofs out by yourself. ;) Marshaling is a part of COM core. I doubt if somebody in Redmond let you in the code. :D
George2
April 4th, 2008, 09:33 AM
Thanks Igor,
Good reference, I think this time I dig too much into the kernel.
Well, not directly (again, I do not understand your terminology). Crossing apartment boundaries results in involving marshaling mechanism. And the one takes care about placing the message into target apartment's message queue.
The citation from Understanding and Using COM Threading Models (http://msdn2.microsoft.com/en-us/library/ms809971.aspx)
Afraid, you have to either take my word or find your proofs out by yourself. ;) Marshaling is a part of COM core. I doubt if somebody in Redmond let you in the code. :D
regards,
George
codeguru.com
Copyright Internet.com Inc., All Rights Reserved.