I have a thread that creates COM objects that require a single threaded apartment.
Originally, this thread's main function put it into a WaitForMultipleObjects loop. Evidently this is a problem, because it prevents the COM message pump from doing it's job.
I replaced this with MsgWaitForMultipleObjects as a solution, but now I'm running into an issue: MsgWaitForMultipleObjects sometimes (often) returns WAIT_FAILED, but doesn't set an error.
The code handles a WAIT_FAILED return value by just continuing and trying to call MsgWaitForMultipleObjects again. The call to MsgWaitForMultipleObjects may return WAIT_FAILED a few times (the most I've seen is 9), but then it suddenly works with no problem.
The code is written so that this could potentially go into an infinite loop if the function were returning WAIT_FAILED for a valid reason. I know I should fix this, but at the moment I'm considering it a 'work around' because the MsgWaitForMultipleObjects call will eventually succeed.
This code is being tested on Windows 7, Vista, and XP (all 32-bit, Windows 7 32- and 64-bit).
Does anyone have any idea why this is happening?
The relevant code:
bool run = true;
while (run)
{
DWORD ret = MsgWaitForMultipleObjects(2, events, FALSE, INFINITE,
QS_ALLINPUT);
switch (ret)
{
case WAIT_OBJECT_0:
{
ResetEvent(events[0]);
ProcessWorkQueue();
break;
}
case WAIT_OBJECT_0 + 1:
{
run = false;
break;
}
case WAIT_OBJECT_0 + 2:
{
MSG msg;
while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
DispatchMessage(&msg);
break;
}
case WAIT_FAILED:
{
Logger::Output(L"Wait failed in Notify::Run(), error is "
+ boost::lexical_cast<std::wstring>(GetLastError()));
}
}
}
Example output would be:
Wait failed in Notify::Run(), error is 0
Wait failed in Notify::Run(), error is 0
Wait failed in Notify::Run(), error is 0
Wait failed in Notify::Run(), error is 0
Wait failed in Notify::Run(), error is 0
Wait failed in Notify::Run(), error is 0
Wait failed in Notify::Run(), error is 0
Wait failed in Notify::Run(), error is 0
Wait failed in Notify::Run(), error is 0
// At this point, the wait succeeds
I believe the WAIT_FAILED return value is only occurring after the wait has been broken by a message.