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; }
void CThread::StartThread() { mThreadContinue = true; mThreadID = _beginthread(threadProc,0,this); while (!IsThreadActive()) Base::sleep(1); }
void dgAsyncThread::Terminate() { if (IsThreadActive()) { dgInterlockedExchange(&m_terminate, 1); m_mutex.Release(); Close(); } }
void dgMutexThread::Terminate() { if (IsThreadActive()) { dgInterlockedExchange(&m_terminate, 1); m_callerMutex.Release(); m_myMutex.Release(); Close(); } }
// ------------------------------------------------------------------------- // // NAME: Term - terminates thread (A DANGEROUS THING TO DO on WIN32!!!) // // per thread / own thread // ------------------------------------------------------------------------- // ESTDLTResults CSysThread::Term( bool blocking ) { if (m_hThread != NULL) { bool bRemoteRequest = !IsInThisThread(); if (bRemoteRequest) { // // test to see if still active under lock // (this is an effort to eliminate multiple calls to TerminateThread // which is a particularly nasty function.) // m_Lock.Lock(); // we want to serialize both the "is active" test // _and_ the TerminateThread call if (IsThreadActive()) { // handle is good and thread is not signaled - so must still be active if (TerminateThread(m_hThread, 0)) { m_Lock.Unlock(); if (blocking) WaitForTerm(); } else { // TerminateThread failed - hmmm... could be that somebody // else killed the thread (or it went away itself) just before // we tried - or some kind of error happened. Nothing else // to do now anyway. m_Lock.Unlock(); } } else { // handle is bad or thread is signaled - either thread // was never active or thread was never terminated. m_Lock.Unlock(); } } else ExitThread(0); } return (STDLT_OK); }
// Called by other thread to kill this thread bool CBasicUIThread::KillThread() { LogEvent(LE_INFO, "CBasicUIThread::KillThread: Before"); if(!IsThreadActive()) { LogEvent(LE_INFOHIGH, "CBasicUIThread::KillThread(), Thread is already not active"); return true; } PostThreadMessage(WM_QUIT, 0, 0); WaitForSingleObject(*this, INFINITE); LogEvent(LE_INFO, "CBasicUIThread::KillThread: After"); m_hThread = NULL; m_nThreadID = 0; return true; }
bool CBasicUIThread::StartThread() { if(IsThreadActive()) { LogEvent(LE_INFOHIGH, "CBasicUIThread::StartThread, Thread already running"); return true; } if(!CreateThread(0)) { LogEvent(LE_ERROR, "CBasicUIThread::StartThread, CreateThread failed"); return false; } Sleep(100); return true; }
CXPlatThread::THREAD_STATUS CXPlatThread::StartThread(void *pParam, BOOL bStartSuspended) { int iStartFlag; THREAD_STATUS eStatus = GetThreadStatus(); // Check to see if thread is active if (eStatus != NOT_STARTED && eStatus != THREAD_TERMINATED) return (eStatus); // If handle exists, thread already ran at least once if (hThreadHandle) { if (IsThreadActive(hThreadHandle)) return (ALREADY_RUNNING); CloseThreadHandle(); }; pUserParm = pParam; // Start thread iStartFlag = bStartSuspended ? 0 : 1; #if defined(_WIN32) unsigned uThread; // If you are using Visual C++, and you get an error here, // make sure under Project|Settings|C++|Code Generation // that you are linking with the Multithreaded libraries. hThreadHandle = (HANDLE) ::_beginthreadex(NULL, 0, ThreadFunc, (void *) this, iStartFlag, &uThread); // Save whether thread is suspended if (hThreadHandle) bSuspended = bStartSuspended; #else iStartFlag = ::pthread_create(&hThreadHandle, pthread_attr_default, (START_ROUTINE) ThreadFunc, (void *) this); #endif // Return start status return (!hThreadHandle ? CANT_START : THREAD_SUCCESS); };
DWORD CXPlatThread::WaitForThreadCompletion(DWORD dwTimeout) { #if defined(_WIN32) if (!hThreadHandle) return 0; else return (::WaitForSingleObject(hThreadHandle, dwTimeout)); #else if (!hThreadHandle) return (0); if (bDetached) return (INVALID_REQUEST); if (bJoined) return (0); // Bogus kudge because pthread_join doesn't have a timeout if (dwTimeout != INFINITE) { int iMaxWait = dwTimeout; int iCurWait = 0; BOOL bTimeout = TRUE; do { // Wait for the thread to complete if (!IsThreadActive(hThreadHandle)) { // Thread completed bTimeout = FALSE; break; }; usleep(1); // Wait timeout for it to complete } while(++iCurWait < iMaxWait); if (bTimeout) ::pthread_cancel(hThreadHandle); } bJoined = TRUE; int iRet = 0; if (hThreadHandle) { iRet = ::pthread_join(hThreadHandle, NULL); ::memset(&hThreadHandle, 0, sizeof(hThreadHandle)); } return (iRet); #endif };
CXPlatThread::THREAD_STATUS CXPlatThread::GetThreadStatus() { // Not even allocated? if (!hThreadHandle) return (NOT_STARTED); #if !defined(_WIN32) return (IsThreadActive(hThreadHandle) ? RUNNING : THREAD_TERMINATED); #else DWORD dwTerminationStatus; // Will fail if not a valid handle if (!::GetExitCodeThread(hThreadHandle, (unsigned long *) &dwTerminationStatus)) return (THREAD_TERMINATED); //Check termination status if (dwTerminationStatus == STILL_ACTIVE) return (bSuspended ? SUSPENDED : RUNNING); return (THREAD_TERMINATED); #endif };
// Close all thread handles and rearrange the list: int ThreadList::CloseThreadObject(const int num) { Thread* target = operator[](num); if(target && (!IsThreadActive(num))) { if(target->Next) target->Next->Prev = target->Prev; if(target->Prev) target->Prev->Next = target->Next; if(target == End) End = target->Prev; if(target == Begin) Begin = target->Next; delete target; return --NumOfThreads; } else return -1; }