Re: COM message pump
"George" <George@discussions.microsoft.com> wrote in message
news:9A77B10C-7A1C-4633-87E6-713AB0EB3953@microsoft.com
The thread 1 and 2 from other apartment will call
CallMeManyTimesFromDifferentThreads of component CSTAReentrancy. One
method call to CallMeManyTimesFromDifferentThreads in my
understanding is one message into message queue of STA owning
component CSTAReentrancy, and since the message queue retrieval is
synchronized, no method will be able to invoke on component
CSTAReentrancy until last one returns (in other words, no message to
the message queue will be retrieved until the current message will be
processed and returned by STA owning thread).
From the test, you are correct. But I do not know why?
You have a situation which, roughly, can be modelled like this:
WinMain() {
// main message pump
MSG msg;
while (GetMessage(&msg))
DispatchMessage(&msg);
}
// A message retrieved from the message queue
// ultimately ends up calling this function (e.g. a COM method)
void f() {
// This function in turn calls another function, g().
// For example, g() is the COM runtime function responsible
// for executing out-of-apartment COM calls.
g();
}
void g() {
// It so happens that g() spins its own message pump:
MSG msg;
while (GetMessage(&msg) && !Done())
DispatchMessage(&msg);
// A message retrieved from the message queue here
// may end up calling f() again - just like the one from
// main pump did
}
In this situation, you get the following sequence of nested calls:
WinMain -> f() -> g() -> f() . f ended up indirectly calling itself,
recursively. In other words, f was re-entered. Hence the scenario is
called reentrancy.
while the method is waiting
for pDummy->SomeMethod() call to return, it can be called again
(reentered) on the same thread.
called again means retrieving another message from message queue, and
in my current limited knowledge, owning STA thread will not retrieve
until the whole method CallMeManyTimesFromDifferentThreads returns.
How many times have I already told you that COM spins a message pump
while waiting for an out-of-apartment call to return? A message pump, by
definition (which I also provided), retrieves and dispatches messages.
Your knowledge should have expanded enough by now. If it's still limited
after being told the same thing over and over again, I can't help but
wonder why I continue to waste my time.
Another confusing point is, the dummy object instance is created by
client thread, which is not in the same STA which owns component
CSTAReentrancy. I am not sure whether this character impacts the
result and re-entrance issue?
Of course. If dummy object lived in the same thread, SomeMethod call in
CallMeManyTimesFromDifferentThreads would be a direct call rather than a
cross-apartment call. COM runtime is not involved in a direct call, so
there would be no message pump while waiting for the call to return: the
call would just run synchronously.
Reentrancy only occurs when a COM method makes a cross-apartment COM
call, or enters a message pump in some other way (e.g. shows a modal
dialog, which also runs its own message pump).
--
With best wishes,
Igor Tandetnik
With sufficient thrust, pigs fly just fine. However, this is not
necessarily a good idea. It is hard to be sure where they are going to
land, and it could be dangerous sitting under them as they fly
overhead. -- RFC 1925