[Insight-developers] Win32OuptutWindow
Brad King
brad.king at kitware.com
Mon Aug 15 19:58:59 EDT 2005
Karthik Krishnan wrote:
> I just spent a couple of annoying hours trying to see why a few tests
> were failing on the Windows platforms. I'll post this message lest
> somebody runs into the same problem again.
>
> The filter had its debug flag set to on. Apparently, Win32OutputWindow
> hangs after a while causing the code itself to suspend if the filter is
> multi-threaded !
I just investigated this and here is what happens. When debug mode is
on then any Get method called on a filter produces a message that is
sent to the output window. In the case of a multi-threaded filter
several threads may call Get methods at the same time.
The Win32OutputWindow is implemented with a SendMessage call to the
Windows API. This call is meant to send a message to a window and wait
for the event to be processed. There are two cases for SendMessage:
1.) The calling thread is the thread that created the window to which
the message is sent. This thread processes messages until the sent
message is handled and then the call returns.
2.) The calling thread is a different thread than that which created the
windows. The message is sent and the calling thread blocks until the
message is processed by the thread that created the window.
Now say we have a 2-threaded filter. The main thread created the output
window. Both threads send a message for each iteration of some loop
(due to a Get call with debugging enabled). Each time the main thread
sends a message it processes that event and any others already queued by
the second thread, and then both threads continue. Then in the last
iteration say the main thread sends its message just before the second
thread does. It will not see the second thread's message and will
return after processing only its own message. Then the second thread
queues the last message and blocks waiting for the main thread to
process its message. Meanwhile the main thread has moved on to this
code in MultiThreader::SingleMethodExecute:
for (thread_loop = 1; thread_loop < m_NumberOfThreads; thread_loop++ )
{
WaitForSingleObject(process_id[thread_loop], INFINITE);
}
The main thread is now blocking waiting for the second thread and
WaitForSingleObject DOES NOT PROCESS MESSAGES. The second thread is
blocking waiting for the main thread to process its message. Deadlock
has been reached.
There are multiple problems this exposes:
1.) Get methods should probably not be called from threaded filters.
All needed information should be copied to local data for each thread by
the main thread before threaded execution begins. This way there is no
access to the filter object by multiple threads simultaneously.
2.) The Win32OutputWindow should be written with thread-safety in mind.
Perhaps the SendMessage calls should be replaced by PostMessage which
will not block while waiting for the message to be executed. Since it
is output only this should not cause a problem.
3.) The MultiThreader could be fixed to deal with the possibility it is
being used by a thread that created windows. The documentation for
WaitForSingleObject states that it should not be called by a thread that
creates windows. Instead MsgWaitForMultipleObjects should be used. I
don't think this kind of responsibility should fall on MultiThreader though.
I propose that solutions #1 and #2 be investigated but I have no time to
do it myself.
Comments?
-Brad
More information about the Insight-developers
mailing list