DWORD CThread::DestroyThread(BOOL bQueue) { MSG sMsg; DWORD dwExitCode; if (IsThreadActive()) { for (SetEvent(m_hObject), PostThreadMessage(WM_QUIT, 0, 0); GetThreadID() != GetCurrentThreadId() && ((!bQueue && WaitForSingleObject(m_hThread, INFINITE)) || (bQueue && MsgWaitForMultipleObjects(1, &m_hThread, FALSE, INFINITE, QS_PAINT | QS_TIMER | QS_POSTMESSAGE | QS_SENDMESSAGE) == WAIT_OBJECT_0 + 1)); ) { if (PeekMessage(&sMsg, (HWND)NULL, 0, 0, PM_QS_PAINT | PM_QS_POSTMESSAGE | PM_QS_SENDMESSAGE | PM_REMOVE)) { if (!AfxPreTranslateMessage(&sMsg)) { TranslateMessage(&sMsg); DispatchMessage(&sMsg); } } RestoreWaitCursor(); } dwExitCode = GetThreadStatus(); CloseHandle(m_hThread); CommonConstruct(); m_bAutoDelete = 0; return dwExitCode; } return 0; }
DWORD CThread::Wait(DWORD dwTimeout, BOOL bQueue) { MSG sMsg; BOOL bMessage; DWORD dwTime[2]; DWORD dwWaitCode; DWORD dwWaitDelay; DWORD dwWaitTime[2]; DWORD dwWaitInterval[2]; for (dwWaitInterval[0] = dwTimeout, dwWaitTime[0] = dwTime[0] = GetTickCount(), SwitchToThread(), dwTime[1] = GetTickCount(), m_bInWait = TRUE, dwWaitCode = WaitForSingleObject(m_hObject, (dwWaitDelay = (dwTime[1] >= dwTime[0]) ? (dwTime[1] - dwTime[0]) : (MAXDWORD - dwTime[0] + dwTime[1] + 1))), dwWaitInterval[0] = (dwWaitInterval[0] != INFINITE) ? ((dwWaitInterval[0] > 2 * dwWaitDelay) ? (dwWaitInterval[0] - 2 * dwWaitDelay) : 0) : dwWaitInterval[0]; (dwWaitCode = ((dwWaitCode == WAIT_TIMEOUT || dwWaitCode == WAIT_OBJECT_0 + 1) && (dwWaitInterval[0] > 0 || bQueue)) ? MsgWaitForMultipleObjectsEx(1, &m_hObject, dwWaitInterval[0], QS_ALLINPUT, MWMO_INPUTAVAILABLE) : ((dwWaitCode != WAIT_TIMEOUT && dwWaitCode != WAIT_OBJECT_0 + 1) ? dwWaitCode : WAIT_TIMEOUT)) == WAIT_OBJECT_0 + 1; dwWaitInterval[1] = ((dwWaitTime[1] = GetTickCount()) >= dwWaitTime[0]) ? (dwWaitTime[1] - dwWaitTime[0]) : (MAXDWORD - dwWaitTime[0] + dwWaitTime[1] + 1), dwWaitInterval[0] = (dwTimeout != INFINITE) ? ((dwWaitInterval[0] >= dwWaitInterval[1]) ? (dwWaitInterval[0] - dwWaitInterval[1]) : 0) : dwTimeout, dwWaitTime[0] = dwWaitTime[1], m_bInWait = TRUE) { for (m_dwTime = GetCurrentTime(), m_bInWait = FALSE; (bMessage = PeekMessage(&sMsg, (HWND)NULL, 0, 0, PM_REMOVE)); ) { if (!AfxPreTranslateMessage(&sMsg)) { TranslateMessage(&sMsg); DispatchMessage(&sMsg); } break; } if (dwWaitCode == WAIT_TIMEOUT && !bMessage && bQueue) break; } return(((m_dwTime = GetCurrentTime()) >= 0) ? dwWaitCode : WAIT_FAILED); }
DWORD CThread::Wait(LPHANDLE phObjects, DWORD nCount, BOOL bAll, DWORD dwTimeout, BOOL bQueue) { MSG sMsg; BOOL bMessage; DWORD nObjects; DWORD dwTime[2]; DWORD dwWaitCode; DWORD dwWaitDelay; DWORD dwWaitTime[2]; DWORD dwWaitInterval[2]; HANDLE hObjects[MAXIMUM_WAIT_OBJECTS + 1] = { m_hObject }; for (dwWaitInterval[0] = dwTimeout, dwWaitTime[0] = dwTime[0] = GetTickCount(), SwitchToThread(), dwTime[1] = GetTickCount(), CopyMemory(&hObjects[1], phObjects, (nObjects = min(nCount, sizeof(hObjects) / sizeof(HANDLE) - 1))*sizeof(HANDLE)), m_bInWait = TRUE, dwWaitCode = WaitForMultipleObjects(nObjects + 1, hObjects, bAll, (dwWaitDelay = (dwTime[1] >= dwTime[0]) ? (dwTime[1] - dwTime[0]) : (MAXDWORD - dwTime[0] + dwTime[1] + 1))), dwWaitInterval[0] = (dwWaitInterval[0] != INFINITE) ? ((dwWaitInterval[0] > 2 * dwWaitDelay) ? (dwWaitInterval[0] - 2 * dwWaitDelay) : 0) : dwWaitInterval[0]; (dwWaitCode = ((dwWaitCode == WAIT_TIMEOUT || dwWaitCode == WAIT_OBJECT_0 + nObjects + 1) && (dwWaitInterval[0] > 0 || bQueue) && !bAll) ? MsgWaitForMultipleObjectsEx(nObjects + 1, hObjects, dwWaitInterval[0], QS_ALLINPUT, MWMO_INPUTAVAILABLE) : (((dwWaitCode != WAIT_TIMEOUT && dwWaitCode != WAIT_OBJECT_0 + nObjects + 1) || bAll) ? dwWaitCode : WAIT_TIMEOUT)) == WAIT_OBJECT_0 + nObjects + 1 || (bAll && dwWaitInterval[0] > 0 && dwWaitCode == WAIT_TIMEOUT); dwWaitInterval[1] = ((dwWaitTime[1] = GetTickCount()) >= dwWaitTime[0]) ? (dwWaitTime[1] - dwWaitTime[0]) : (MAXDWORD - dwWaitTime[0] + dwWaitTime[1] + 1), dwWaitInterval[0] = (dwTimeout != INFINITE) ? ((dwWaitInterval[0] >= dwWaitInterval[1]) ? (dwWaitInterval[0] - dwWaitInterval[1]) : 0) : dwTimeout, dwWaitTime[0] = dwWaitTime[1], dwWaitCode = (bAll) ? WaitForMultipleObjects(nObjects + 1, hObjects, bAll, (!HIWORD(GetQueueStatus(QS_ALLINPUT))) ? min(dwWaitDelay, dwWaitInterval[0]) : 0) : dwWaitCode, m_bInWait = TRUE) { for (m_dwTime = GetCurrentTime(), m_bInWait = FALSE; (bMessage = PeekMessage(&sMsg, (HWND)NULL, 0, 0, PM_REMOVE)); ) { if (!AfxPreTranslateMessage(&sMsg)) { TranslateMessage(&sMsg); DispatchMessage(&sMsg); } break; } if (dwWaitCode == WAIT_TIMEOUT && !bMessage && bQueue) break; } return(((m_dwTime = GetCurrentTime()) >= 0) ? dwWaitCode : WAIT_FAILED); }
static BOOL AfxInternalPumpMessage() { _AFX_THREAD_STATE *pState = AfxGetThreadState(); if (!::GetMessage(&(pState->m_msgCur), NULL, NULL, NULL)) { /*!!! #ifdef _DEBUG TRACE(traceAppMsg, 1, "CWinThread::PumpMessage - Received WM_QUIT.\n"); pState->m_nDisablePumpCount++; // application must die #endif */ // Note: prevents calling message loop things in 'ExitInstance' // will never be decremented return FALSE; } #ifdef _DEBUG /*!!! if (pState->m_nDisablePumpCount != 0) { TRACE(traceAppMsg, 0, "Error: CWinThread::PumpMessage called when not permitted.\n"); ASSERT(FALSE); } */ #endif #ifdef _DEBUG //!!! _AfxTraceMsg(_T("PumpMessage"), &(pState->m_msgCur)); #endif // process this message if (pState->m_msgCur.message != WM_KICKIDLE && !AfxPreTranslateMessage(&(pState->m_msgCur))) { ::TranslateMessage(&(pState->m_msgCur)); ::DispatchMessage(&(pState->m_msgCur)); } return TRUE; }