I have an application which second thread calls GetMessage()
in a loop. At some point the first thread realizes that the user wants to quit the application and notifies the second thread that it should terminate. As the second thread is stuck on GetMessage()
, the program never quits. Is there a way to wait for messages with a timeout?
I’m open to other ideas too.
EDIT: (additional explanations)
The second thread runs that snippet of code:
while ( !m_quit && GetMessage( &msg, NULL, 0, 0 ) )
{
TranslateMessage( &msg );
DispatchMessage( &msg );
}
The first thread sets m_quit
to true.
You should be able to post a quit message to the second thread with
PostThreadMessage
.E.g.
You shouldn't need to read the
m_quit
variable in the second thread but you should check for errors fromGetMessage
as well as a return value ofFALSE/0
which is what is returned if the next message is a quit message.Not tested, but you could try the function MsgWaitForMultipleObjects without actually any object.
If if returns
WAIT_TIMEOUT
it is a timeout, but if it returnsWAIT_OBJECT_0
you can callGetMessage
with guarantee not to be blocked.But note the following:
So you have to ensure that the last time you called any of the message functions there is no messages left on the queue, or you will have a kind of race condition.
Probably your best option would be to replace
GetMessage
with:But as I said before, I didn't test it so I cannot be sure if it will work.
The easiest way is to just call
UINT_PTR timerId=SetTimer(NULL, NULL, 1000, NULL)
before callingGetMessage
. It will post aWM_TIMER
message to the calling thread every second, so theGetMessage
will return promptly. Then, callKillTimer(NULL, timerId)
to cancel it.UPDATE Sample code:
Yep. Try
PeekMessage()
instead. But I think this will not be full problem solving.One thing you can always do is just send the blocked thread a user-defined message that will cause it to wake up, process the message, then go back up to the top of the loop. In fact, it might be easiest to completely remove the
m_quit
variable and instead to just send the main thread a message that says "you need to quit now."Hope this helps!