Once I thought all calls across COM apartments (not inside apartment) are all synchronous call, now after study re-entrancy problem, I think I am wrong, at least STA to MTA call is asynchronous.
(Link to re-entrancy problem, http://www.codeproject.com/KB/COM/sta_issues.aspx)
After some study, I can not find a conclusion whether the 4 types of calls are synchronous or asynchronous. Here is my study result, please feel free to correct me if I am wrong?
1. STA --> STA, I think asynchronous;
2. STA --> MTA, I think asynchronous;
3. MTA --> STA, I think synchronous;
4. MTA --> MTA, I think synchronous.
thanks in advance,
George
Igor Vartanov
April 7th, 2008, 02:05 PM
Any COM interface call is synchronous: client's thread gets blocked until server returns. I dare say this is absolutely normal in aspect of thread code execution.
Re-entrancy problem you mentioned has absolutely different nature:
The problem comes from the fact that client makes an outgoing call back on the COM component passed in the event's function.The client's thread is blocked while the STA message queue has to be engaged by an ingoing call from event handler. So the problem is the specific comonent condition existing to the moment of call: message queue is associated with the thread, and the thread is blocked by a cross-thread call, and therefore the queue is blocked as well. And the case has nothing to do with the mentioned call sinchronism. In this situation the server behaviour looks perfectly stupid (!): it gives the interface out while being impossible to process ingoing calls. The normal behaviour would be running special thread for firing event while its main thread continues to accept calls.
By the way, the perfectly same situation is present, when thread A sends message to thread B, and message handler in thread B sends message back to thread A. Such a deadlock on some reason does not cause such a storm of emotions among Windows developers. :)
George2
April 8th, 2008, 12:19 AM
Thanks Igor,
Two more comments,
1.
The problem comes from the fact that client makes an outgoing call back on the COM component passed in the event's function.
What do you mean "the event function"? Do you mean the pointer of component of other apartment passed into STA (during function call to STA) as the parameter, so that STA can use the pointer of component of other apartment to make a callback?
2.
So the problem is the specific comonent condition existing to the moment of call:
What do you mean "comonent condition"? I can not find the word in my dictionary.
regards,
George
Igor Vartanov
April 8th, 2008, 12:09 PM
1.
What do you mean "the event function"? Do you mean the pointer of component of other apartment passed into STA (during function call to STA) as the parameter, so that STA can use the pointer of component of other apartment to make a callback?I mean, the component interface pointer was passed from STA to event handling function while component has been firing event. Sorry, I've caught a cold, so I might express myself too much unclear. :)
2.
What do you mean "comonent condition"? I can not find the word in my dictionary.
Sorry, that was a typo. Read "component condition".
George2
April 9th, 2008, 03:35 AM
Thanks and it is ok, Igor,
I want to clarify three things with you. :-)
1.
In your post #2, what means "call sinchronism"? I can not find it in my dictionary.
2.
In your post #2, "be engaged by an ingoing call from event handler" means the following code or something executed by STA owning thread?
MSG msg;
while (GetMessage (&msg, 0, 0, 0))
DispatchMessage (&msg);
3.
We need to have a common terminology and scenario about STA re-entrancy issue.
I think you mean the re-entrancy issue like this, client apartment calls STA component and pass in interface pointer, the interface pointer is used for STA owning thread to callback to client.
Then, STA processes the message queue, and processes the message, and it will also callback the event handler function in the client, through the interface pointer passed into STA before.
My description correct about your scenario?
I mean, the component interface pointer was passed from STA to event handling function while component has been firing event. Sorry, I've caught a cold, so I might express myself too much unclear. :)
regards,
George
Igor Vartanov
April 9th, 2008, 11:38 AM
1. Does "synchronism" sound better? :)
2. I'll try to re-phrase: client thread is blocked while ingoing call happens.
3. Client STA provides (advises) callback interface for firing event. Server STA fires event, i.e. calls some callback interface method, that makes the server STA thread to remain blocked until call returns. Meanwhile, some server STA interface is passed to client STA as a callback parameter. Client STA calls that interface, and client's STA gets blocked until call returns. As long as the ingoing call to server STA gets transformed to a window message, and that message is placed into server STA thread's message queue, a deadlock takes place - message never gets processed because of server thread's blocked state (message queue is not pumped).
George2
April 12th, 2008, 03:19 AM
Thanks Igor,
I think you are talking about deadlock issue for STA, other than re-entrancy issue for STA. Refer to the below tutotial for them with code,
http://www.codeproject.com/KB/COM/sta_issues.aspx
You mentioned "the server STA thread to remain blocked until call returns", is not correct in the situation of STA re-entrancy issue. In STA re-entrancy issue, when STA owning thread makes out-going call to other apartment, the thread will not be blocked and will continue to pump message queue.
I have debugged it. Any comments? If I am wrong, please feel free to correct me. :-)
3. Client STA provides (advises) callback interface for firing event. Server STA fires event, i.e. calls some callback interface method, that makes the server STA thread to remain blocked until call returns. Meanwhile, some server STA interface is passed to client STA as a callback parameter. Client STA calls that interface, and client's STA gets blocked until call returns. As long as the ingoing call to server STA gets transformed to a window message, and that message is placed into server STA thread's message queue, a deadlock takes place - message never gets processed because of server thread's blocked state (message queue is not pumped).
regards,
George
Igor Vartanov
April 14th, 2008, 12:03 PM
Thanks Igor,
I think you are talking about deadlock issue for STA, other than re-entrancy issue for STA. Refer to the below tutotial for them with code,
http://www.codeproject.com/KB/COM/sta_issues.aspx
You mentioned "the server STA thread to remain blocked until call returns", is not correct in the situation of STA re-entrancy issue. In STA re-entrancy issue, when STA owning thread makes out-going call to other apartment, the thread will not be blocked and will continue to pump message queue.
I have debugged it. Any comments? If I am wrong, please feel free to correct me. :-)
Well, I cannot say now that you're wrong, though some aspect exists where I'm right. So you can consider it your self (see project attached).
The key fragment is
RunThread<0>(hWait[0], obj);
RunThread<0>(hWait[1], obj);
RunThread<0>(hWait[2], obj);
RunThread<0>(hWait[3], obj);
obj->Test(pDisp, GetCurrentThreadId());
When object's apartment is the STA of the main thread, the very last line remains waiting for closure of all the other STA calls. I have no clue why this happens, and frankly, have no time to delve into this issue.
codeguru.com
Copyright Internet.com Inc., All Rights Reserved.