UINT InstallMain(LPVOID pParam) { LPINSTALL_INFO pInfo=(LPINSTALL_INFO)pParam; PostMessage( pInfo->hMainWnd, WM_USER_INSTALL_PROGRESS, 0, 0 ); for( int i=0; i<pInfo->pStringArray->GetSize(); i++ ) { CString sFileName = pInfo->pStringArray->ElementAt(i); ::SendMessage( pInfo->hMainWnd, WM_USER_INSTALL_MESSAGE, PROG_NEWGROUPMSG, (DWORD)sFileName.GetBuffer(sFileName.GetLength()+1) ); ::SendMessage( pInfo->hMainWnd, WM_USER_INSTALL_PROGRESS, 0, NULL ); sFileName.ReleaseBuffer(); CPackage pac; pac.m_nType = pInfo->nType; pac.m_bIsZipped = ( sFileName.GetLength() > 4 && 0 == sFileName.Right(4).CompareNoCase(".zip") ); pac.m_strDescript = sFileName; pInfo->pNetDB->InstallPackageEx( pac, sFileName, InstallCallback, pInfo->hMainWnd ); // User wants to quit program if(WAIT_OBJECT_0 == WaitForSingleObject(CInstallPacDlg::m_hEventKillInstallThread,0) ) { ::PostMessage( pInfo->hMainWnd, WM_USER_INSTALL_END, FALSE, 0 ); SetEvent(CInstallPacDlg::m_hEventInstallThreadKilled); AfxEndThread( 0, TRUE ); return 0; } } ::SendMessage( pInfo->hMainWnd, WM_USER_INSTALL_END, TRUE, 0 ); AfxEndThread( 0, TRUE ); return 0; }
UINT CSTThread::BodyThread() { HANDLE TabHandle[MAX_EVENTS]; UINT NbAdditionalEvents=0; DWORD WaitThreadRes=0; CEvent *pTabEvents[MAX_EVENTS]; NbAdditionalEvents=GetAdditionalEvents(pTabEvents); if (NbAdditionalEvents>=MAX_EVENTS) { AfxEndThread(STOP_ON_CFG); return STOP_ON_CFG; } TabHandle[0]=m_EventStop; m_EventStop.ResetEvent(); for (UINT i=0;i<NbAdditionalEvents;i++) { TabHandle[i+1]=*(pTabEvents[i]); pTabEvents[i]->ResetEvent(); } while (TRUE) { WaitThreadRes=::WaitForMultipleObjects(NbAdditionalEvents+1, TabHandle, FALSE, GetWaitEventDelay()); // Did we receive an event? if ( (WaitThreadRes>=WAIT_OBJECT_0) && (WaitThreadRes<WAIT_OBJECT_0+NbAdditionalEvents+1) ) { if (WaitThreadRes==WAIT_OBJECT_0) { AfxEndThread(STOP_ON_EVENT); return STOP_ON_EVENT; } else { if (!TreatEvent(WaitThreadRes-WAIT_OBJECT_0-1)) { AfxEndThread(STOP_ON_EVENT); return STOP_ON_EVENT; } } } // No, let's do our job else { if (!RunThread()) { // Job finished! AfxEndThread(STOP_ON_RUN); return STOP_ON_RUN; } } } return 0; }
unsigned long CIRDriver::readdata(unsigned long maxusec, HANDLE ThreadEvent) { unsigned long int x=0; HANDLE events[2]={hDataReadyEvent,ThreadEvent}; int evt; if(ThreadEvent==NULL) evt=1; else evt=2; if(GetData(&x)==false) { ResetEvent(hDataReadyEvent); int res; if(maxusec) res=WaitForMultipleObjects(evt,events,FALSE,(maxusec+500)/1000); else res=WaitForMultipleObjects(evt,events,FALSE,INFINITE); if(res==(WAIT_OBJECT_0+1)) { DEBUG("Unknown thread terminating (readdata)\n"); AfxEndThread(0); return 0; } GetData(&x); } return x; }
// 分发接收数据的线程 UINT TSDispatchThreadMain( LPVOID pParam ) { while( TRUE ) { UINT nMsgType = 0; PRCV_DATA pRCV_DATA = NULL; if( CTSCache::GetInstance().PopPacket( nMsgType, pRCV_DATA ) ) { ASSERT( pRCV_DATA && pRCV_DATA->m_pData ); if( pRCV_DATA && pRCV_DATA->m_pData ) CTSWnd::GetInstance().SendMessage( nMsgType, (LPARAM)pRCV_DATA ); CTSCache::GetInstance().FreePacket( pRCV_DATA ); } Sleep( 1000 ); // User wants to quit program if(WAIT_OBJECT_0 == WaitForSingleObject(CTSWnd::m_hEventKillDispatchThread,0) ) { SetEvent(CTSWnd::m_hEventDispatchThreadKilled); AfxEndThread( 0, TRUE ); return 0; } } }
BOOL CPowerMateThread::InitInstance() { //mixerOpen(&m_mixer, 0, NULL, 0, MIXER_OBJECTF_WAVEOUT); char reportBuffer[8]; DWORD txdBytes; BOOL result; m_OldButtonState = 0; //m_pDlgWnd->m_AxisDataEditCtrl.SetWindowText("0"); //m_pDlgWnd->m_ButtonDataEditCtrl.SetWindowText("Up"); m_Running = TRUE; while (m_Running == TRUE) { result = ReadFile(m_hPowerMate, reportBuffer, sizeof(reportBuffer), &txdBytes, NULL); if (result) { if( txdBytes == 7) PerformAction(m_hPowerMate, reportBuffer); } else break; } AfxEndThread(0); // avoid entering standard message loop by returning FALSE return FALSE; }
UINT __cdecl WorkProc(LPVOID pParam) { ((CAgentMonitorDlg*)pParam)->OnThreadWorkProc(); AfxEndThread(0, FALSE); return 0; }
UINT CHeartbeatThread::HeartbeatThreadFunction(LPVOID pParam) { pParent = static_cast<CHeartbeatThread*>(pParam); // Seed the RNG srand((unsigned)GetTickCount()); while (true) { _heartbeat_counter++; write_log(preferences.debug_heartbeat(), "[HeartBeatThread] Starting next cycle\n"); // Check event for stop thread if(::WaitForSingleObject(pParent->_m_stop_thread, 0) == WAIT_OBJECT_0) { // Set event ::SetEvent(pParent->_m_wait_thread); AfxEndThread(0); } LogMemoryUsage("Begin of heartbeat thread cycle"); p_tablemap_loader->ReloadAllTablemapsIfChanged(); if (p_autoconnector->IsConnected()) { if (IsWindow(p_autoconnector->attached_hwnd())) { ScrapeEvaluateAct(); } else { // Table disappeared p_autoplayer->EngageAutoplayer(false); p_autoconnector->Disconnect(); } } else { // Not connected AutoConnect(); } FlexibleHeartbeatSleeping(); write_log(preferences.debug_heartbeat(), "[HeartBeatThread] Heartbeat cycle ended\n"); } }
/******************************************************** parseFieldCodes -- parse IIS and others field codes #Fields: time c-ip cs-method cs-uri-stem sc-status ********************************************************/ void parseFieldCodes(applSettings *SettingsPtr,char *buf) { char *ptr=buf; int i,status; try { //Ignore first '#Field' status=sscanf_s(ptr,"%s",&(SettingsPtr->fieldCodes[0][0]),sizeof(SettingsPtr->fieldCodes[0])); if (status!=1) { //failed SettingsPtr->fieldCodes[0][0]='\0'; return; } ptr+=strlen(SettingsPtr->fieldCodes[0])+1; for(i=0;i<32;i++) { status=sscanf_s(ptr,"%s",&(SettingsPtr->fieldCodes[i][0]),sizeof(SettingsPtr->fieldCodes[i])); if (status!=1) { SettingsPtr->fieldCodes[i][0]='\0'; break; } if (SettingsPtr->fieldCodes[i]=="s-sitename") SettingsPtr->fieldCodeProcessIsPresent=true; ptr+=strlen(SettingsPtr->fieldCodes[i])+1; } if (i>0) { DEBUGAPPLPARSE(Informational,"Identified %d field codes in application log for %s.",i,SettingsPtr->ApplicationName); } } catch (...) { logger(Error,"Exception in Application parsings parseFieldCodes. Application logging of %s cannot continue due to exception. The line being parsed:%s",SettingsPtr->ApplicationName,buf); CreateMiniDump(NULL); AfxEndThread(0,true); } }
UINT RxPeripheralDataThread(LPVOID param) { unsigned char streamBuffer = 0; DWORD numBytesRead = 0; DWORD numBytesWritten = 0; CTouchScreenDlg* touchScreenDlg = (CTouchScreenDlg*) param; while(1) { if(touchScreenDlg->m_peripherals.m_killReadSerialPortThread) { AfxEndThread(0, true); } else { touchScreenDlg->m_peripherals.ReadPort(&streamBuffer, 1, numBytesRead); TRACE("Byte read from serial port: [%d]\n\n", streamBuffer); TRACE("Number of bytes read: %d\n", numBytesRead); touchScreenDlg->PostMessage(SENSOR_STATE_MSG, streamBuffer, 0); streamBuffer = 0; Sleep(25); } } return true; }
// Check for a stop scanning (or kill) of the background thread bool CHexEditDoc::AerialProcessStop() { bool retval = false; CSingleLock sl(&docdata_, TRUE); switch(aerial_command_) { case STOP: // stop scan and wait TRACE1("+++ BGAerial: stop for %p\n", this); retval = true; break; case DIE: // terminate this thread TRACE1("+++ BGAerial: killed thread for %p\n", this); aerial_state_ = DYING; sl.Unlock(); // we need this here as AfxEndThread() never returns so d'tor is not called delete[] aerial_buf_; aerial_buf_ = NULL; AfxEndThread(1); // kills thread (no return) break; // Avoid warning case NONE: // nothing needed here - just continue scanning break; default: // should not happen ASSERT(0); } // Prevent reprocessing of the same command aerial_command_ = NONE; return retval; }
// 分发数据线程 UINT TSDispatchThreadMain(LPVOID pParam) { while(TRUE) { UINT nMsgType = 0; PRCV_DATA pRCV_DATA = NULL; if (CTSCache::GetInstance().PopPacket(nMsgType, pRCV_DATA)) { ASSERT(pRCV_DATA && pRCV_DATA->m_pData); if (pRCV_DATA && pRCV_DATA->m_pData) CTSWnd::GetInstance().SendMessage(nMsgType, (LPARAM)pRCV_DATA); char szText[256]; sprintf(szText, "↑DataType:%d PacketNum:%d", pRCV_DATA->m_wDataType, pRCV_DATA->m_nPacketNum); g_pWinTrace->Debug()->Send("TSDispatchThreadMain", szText); CTSCache::GetInstance().FreePacket(pRCV_DATA); } Sleep(1); // User wants to quit program if (WAIT_OBJECT_0 == WaitForSingleObject(CTSWnd::m_hEventKillDispatchThread,0)) { SetEvent(CTSWnd::m_hEventDispatchThreadKilled); AfxEndThread(0, TRUE); return 0; } } }
UINT CCaptureAudio::OnDataThread(LPVOID lParam)//LPVOID* lParam) { #define FLAG _T("{5DDA0840-6AE0-4c1b-9488-35F95396E4A8}") HANDLE handle=::CreateMutex(NULL,FALSE,FLAG); if(GetLastError()==ERROR_ALREADY_EXISTS) { return 0; } CCaptureAudio* pControler=(CCaptureAudio *)lParam; if(!pControler) { return 0; } int nState=0; while(!pControler->m_bThreadExit) { // 检测是否有关闭本线程的信号 DWORD dwEvent = WaitForSingleObject(pControler->m_hThreadEvent, 10); if (dwEvent == WAIT_OBJECT_0) { AfxEndThread(0,TRUE); return 0; } pControler->OnThreadDeal(); } return 0; }
UINT recvFromPcie(LPVOID pParam) { PACKET packet; CBroadGrdDlg* pDlg=(CBroadGrdDlg*)pParam; while(true) { WaitForSingleObject(pcieReceiver->sem_packet_rec,INFINITE); //WaitForSingleObject(pcieReceiver->queue_Mutex, INFINITE); packet=pcieReceiver->qBuff.front(); pcieReceiver->qBuff.pop(); //ReleaseMutex(pcieReceiver->queue_Mutex); SoftwareCommendHeadr* header=(SoftwareCommendHeadr*)(packet.buf+1); switch(header->function) { case Func_DeliverConfig: { Cmd_DeliverConfig* cmd=(Cmd_DeliverConfig*)header; pDlg->recvFile(cmd->frameID,cmd->frameSize,cmd->endFlag,cmd->data); } break; default: break; } } //caper->sendPacket(0,HWND_Master,(u_char*)lParam,packet.len); AfxEndThread(0); return 0; }
int mfc_worker::ExitInstance() { w_result = w_on_quit(); CWinThread::ExitInstance(); AfxEndThread(w_result, 1); // simply returning doesn't delete the_worker return w_result; // not reached }
void CSimplexDlg::endSystem() { SetLedOff(1); CmenuDlg *ppDlg = (CmenuDlg*)AfxGetApp()->m_pMainWnd; SystemTime(); ppDlg->m_Hist.SetSel(ppDlg->m_Hist.GetWindowTextLength(), -1); //获取当前编辑框字符 ppDlg->m_Hist.ReplaceSel(_T("End the Thread.\r\n")); AfxEndThread(0, TRUE); }
UINT CBaseDlg::MakeTunnelThread(LPVOID param) { ConnectParam* pThis = (ConnectParam*)param; bool bRes = false; HWND hWnd = NULL; TunnelMode mode = NONE; pThis->bMaking = true; if (gl_pLogger) gl_pLogger->log_info("CBaseDlg::MakeTunnelThread begin..."); #define _ServerSocket pThis->pServerSocket #define _ClientSocket pThis->pClientSocket try { if (pThis) { hWnd = pThis->hWnd; mode =pThis->mode; if (_ServerSocket && _ClientSocket) { if (pThis->bServer) { if (_ServerSocket->CreateServerSocket(pThis->nPort)) { ::PostMessage(hWnd, WM_MAKETUNNELWAIT, 0, 0); bRes = _ServerSocket->WaitForConnection(); } } else { int nRetry = 0; while (!bRes && nRetry < 5) //try to create connection for 5 times. { bRes = _ClientSocket->CreateClientSocket(pThis->IpAddress, pThis->nPort); nRetry ++; if (!bRes) Sleep(1000); } if (bRes) OutputDebugString("_ClientSocket->CreateClientSocket OK\n"); else OutputDebugString("_ClientSocket->CreateClientSocket failed.\n"); } } } } catch(...){} if (IsWindow(hWnd)) ::PostMessage(hWnd, WM_MAKETUNNELEND, (WPARAM)bRes, (LPARAM)mode); pThis->bMaking = true; AfxEndThread(0); return 0; }
UINT CSubtitleDlDlg::RunThread(LPVOID pParam) { PTHREADSTRUCT pTA = reinterpret_cast<PTHREADSTRUCT>(pParam); if (!OpenUrl(pTA->is, CString(pTA->url), pTA->raw_list)) { ::PostMessage(pTA->hWND, UWM_FAILED, (WPARAM)0, (LPARAM)0); AfxEndThread(1, TRUE); } ::PostMessage(pTA->hWND, UWM_PARSE, (WPARAM)0, (LPARAM)0); return 0; };
UINT OutSumThread(LPVOID pParam) { ThreadParm *parm; parm=(ThreadParm*)pParam;//Parameters CalQuant QuantObj(parm->ThreadID); SetEvent(parm->hEventB); printf("Create Thread %d!\n", QuantObj.ThreadID); CReport tRep; ThreadParm TParm; while(1)//线程一旦创建,会不断等待接受任务,直到主线程发出MSG_THREAD_END命令 { //任务已经完成,所有线程自动终止 if(parm->IsEnd) { QuantObj.PostFalseMsg(MSG_THREAD_END); AfxEndThread(0); return 0; } //等待任务 WaitForSingleObject(parm->hEventP,INFINITE); //检查任务是不是已经处理过,如果是异常分发,忽略,重新等待 if(parm->IsDeal) continue; //检查任务ID是不是发给自己的 //if(parm->ThreadID!=QuantObj.ThreadID) continue; //初始化参数,共享数据区不允许改变 parm->GL_CriticalSection.Lock(); parm->IsDeal=true; TParm=*parm; SetEvent(parm->hEventE); ResetEvent(parm->hEventP); parm->GL_CriticalSection.Unlock(); //开始校正工作,parm可以接受新的参数填充 QuantObj.ExecuteCal(&TParm); //QuantObj.OutPutCalData(&TParm); //产生报告 QuantObj.GenReport(&tRep); tRep.rFile=TParm.RFile; tRep.RawFile=TParm.RawFile; tRep.IsRepValidate=true;//该报告有效,主线程可以从共享区读取 if(!QuantObj.IsOutSuccess) tRep.Error_code|=ERROR_MS1OUTF; parm->SetRepBuff(QuantObj.ThreadID,&tRep); printf("Msg %d: %s!\n", QuantObj.ThreadID,TParm.RFile); //发送任务完成的消息 QuantObj.PostFalseMsg(MSG_TASK_FINISHED); //T_Report(&dFile,&tRep); } }
/** @fn UINT check_timeout_thread_proc(LPVOID pParam) @detail 检查超时并重发数据 @param[in] pParam 该参数是line_socket* @return 返回线程错误信息 @note */ UINT __cdecl line_socket::check_timeout_thread_proc(LPVOID pParam) { line_socket* ls = (line_socket*)pParam; while(true) { // ls->check_timeout_and_resend_data(); if(::WaitForSingleObject(ls->stop_event_.m_hObject, ls->WAITING_FOR_RESP_TIME) == WAIT_OBJECT_0) break; } AfxEndThread(0); return 0; }
void CDebugger::EndThread() { if (!m_pDebugger->m_ExternalDebugging) { FreeConsole(); } ::SendMessage(m_pDebugger->m_hWndMainFrame, DMSG_DEBUG_END, 0, 0); m_pDebugger->Write("The program has exited...\n"); m_pDebugger->m_lua.StopDebugger(); if (!m_pDebugger->m_ExternalDebugging) { AfxEndThread(0); } }
UINT CRobotCore::PointCloudsThread(LPVOID pParam) { CRobotCore* pRobotCore = (CRobotCore*)pParam; if (pRobotCore->m_hShutdownEvent != NULL) ResetEvent(pRobotCore->m_hShutdownEvent); else pRobotCore->m_hShutdownEvent = CreateEvent(NULL, TRUE, FALSE, NULL); if (pRobotCore->m_hToProcessEvent != NULL) ResetEvent(pRobotCore->m_hToProcessEvent); else pRobotCore->m_hToProcessEvent = CreateEvent(NULL, FALSE, FALSE, NULL); // initialize the event objects pRobotCore->m_hEventArray[0] = pRobotCore->m_hShutdownEvent; // highest priority pRobotCore->m_hEventArray[1] = pRobotCore->m_hToProcessEvent; DWORD Event = 0; pRobotCore->m_bThreadAlive = TRUE; while (true) { Event = WaitForMultipleObjects(2, pRobotCore->m_hEventArray, FALSE, INFINITE); switch (Event) { case 0: { // Shutdown event. This is event zero so it will be // the higest priority and be serviced first. pRobotCore->m_bThreadAlive = FALSE; // Kill this thread. break is not needed, but makes me feel better. AfxEndThread(100); break; } case 1: // ToProcess event { pRobotCore->m_ProcessOneFrame(); //pRobotCore->m_cDataHolder.PrintInfo(L"[图像处理]完成一次3D处理"); ResetEvent(pRobotCore->m_hToProcessEvent); break; } } // end switch } return 1L; }
//Может запрашивать действие пользователя и заканчивать поток void CComThread::ReportComErrorAndExit() { LPTSTR lpMsgBuf; FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER|FORMAT_MESSAGE_FROM_SYSTEM| FORMAT_MESSAGE_IGNORE_INSERTS, NULL, GetLastError(),MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR) &lpMsgBuf, 0, NULL); CString str2; DetectSerialErrors(m_hComPort,&str2); LogSpecifiedFileFormat(LogFileName, "ReadFile: ошибка чтения из порта.%s %s",lpMsgBuf,(LPCSTR)str2); LogFileFormat("ReadFile: ошибка чтения из порта.%s %s",lpMsgBuf,(LPCSTR)str2); LocalFree(&lpMsgBuf); m_Pool.PutMsg(NULL,SERIAL_ERROR_COM_FAILED); AfxEndThread(0); }
UINT LoadKDataCacheMain(LPVOID pParam) { AfxGetDB().LoadKDataCache( AfxGetStockContainer(), NULL, NULL, 0, STKLIB_MAX_PROGRESS ); AfxGetStockContainer().OnDataChanged( ); AfxGetStkReceiver().RefreshStockContainer( AfxGetStockContainer(), TRUE ); AfxReloadStockMain( ); ::PostMessage( AfxGetMainWnd()->GetSafeHwnd(), WM_USER_UPDATESLISTVIEW,0, 0 ); ::PostMessage( AfxGetMainWnd()->GetSafeHwnd(), WM_USER_INITDATES, 0, 0 ); AfxEndThread( 0, TRUE ); return 0; }
unsigned int CFrontendApp::RedirectThreadFunc(void) { char Buff[1000]; int Len; int Left, Right; CString Line; CString Int; while (::ReadFile(OutRead, Buff, sizeof (Buff) - 1, (unsigned long *)&Len, NULL)) { if (Len == 0) break; Left = 0; for (Right = 0; Right < Len; Right++) { if (Buff[Right] != 13) Buff[Left++] = Buff[Right]; } Len = Left; Left = 0; for (Right = 0; Right < Len; Right++) { if (Buff[Right] == 10) { Buff[Right] = 0; Line += (Buff + Left); AfxMessageBox(Line); Line.Empty(); Left = Right + 1; } } Buff[Right] = 0; Line += (Buff + Left); } AfxEndThread(0); return 0; }
// ---------------------------------------------------------------------------- // UINT AbstractDMXDriver::run(void) { DMXStudio::log_status( "DMX driver started [%s]", m_connection_info ); while ( isRunning() ) { DMX_STATUS status; status = dmx_send( DMX_PACKET_SIZE+1, m_blackout ? m_blackout_packet : m_packet ); if ( status != DMX_OK ) { DMXStudio::log( "DMX send error %d", status ); } DWORD next_frame = GetTickCount() + getPacketDelayMS(); if ( m_debug ) { CString buffer; for ( channel_t chan=1; chan <= DMX_PACKET_SIZE; chan++ ) { buffer.Format( "%03d=%02x ", chan, m_packet[chan] ); if ( chan % 16 == 0 ) { DMXStudio::log( buffer ); buffer.Empty(); } } if ( buffer.GetLength() != 0 ) DMXStudio::log( buffer ); } Sleep( m_packet_min_delay ); // Minimal sleep time // MTBP - Mark time between packets long sleep_ms = next_frame - GetTickCount(); if ( ::WaitForSingleObject( m_wake.m_hObject, sleep_ms ) == WAIT_OBJECT_0 ) { if ( m_latch ) { memcpy( m_packet, m_pending_packet, sizeof(m_packet) ); m_latch = false; } } } DMXStudio::log_status( "DMX driver stopped [%s]", m_connection_info ); AfxEndThread( DMX_OK ); return DMX_OK; }
/** @fn UINT __cdecl send_processing_thread_proc(LPVOID pParam) @detail 由于OnSend只能在WSAEWOULDBLOCK错误,Accept和Connect时,发送消息,因此需要使用发送线程 @param[in] pParam 该参数是line_socket* @return 返回线程错误信息 @note */ UINT __cdecl line_socket::send_processing_thread_proc(LPVOID pParam) { DWORD dwBytes = 0; line_socket* ls = (line_socket*)pParam; _ASSERTE(ls); SOCKET_PACKAGE_SENT_PTR ptr = NULL; while(true) { if(WaitForSingleObject(ls->stop_event_.m_hObject, ls->RECV_PROCESSING_LOOP_TIME) == WAIT_OBJECT_0) break; ptr = ls->pop_wait_sending_queue(); if(ptr == NULL) continue; dwBytes = ls->Send(ptr->pack_, ptr->size_); if(dwBytes == SOCKET_ERROR) { dwBytes = GetLastError(); if(dwBytes == WSAEWOULDBLOCK) { continue; } else { ls->throw_socket_error(dwBytes); ls->OnClose(dwBytes); } } else { if(ptr->cmd_type_ != 3) { ptr->time_counter_ = 0x0; ++ptr->counter_sent_; ls->push_sent_pack(ptr); } } } AfxEndThread(0); return 0; }
/** @fn UINT __cdecl recv_processing_thread_proc(LPVOID pParam) @detail 接收线程处理接收到的保存在等待处理队列中的数据包 @param[in] pParam 该参数是line_socket* @return 返回线程错误信息 @note */ UINT __cdecl line_socket::recv_processing_thread_proc(LPVOID pParam) { line_socket* ls = (line_socket*)pParam; SOCKET_PACKAGE_RECV_PTR recv_ptr = NULL; std::list<SOCKET_PACKAGE_RECV_PTR>::iterator itr; std::list<SOCKET_PACKAGE_RECV_PTR> tmp_list; while(true) { if(WaitForSingleObject(ls->stop_event_.m_hObject, ls->RECV_PROCESSING_LOOP_TIME) == WAIT_OBJECT_0) break; ls->wait_processing_pack_queue_lock_.Lock(); for(itr = ls->wait_processing_pack_queue_.begin(); itr != ls->wait_processing_pack_queue_.end(); ++itr) { recv_ptr = *itr; if(recv_ptr->cmd_type_ == 3) { ls->process_resp_pack(ls, recv_ptr); } else { ls->process_pack_recvd(ls, recv_ptr); } tmp_list.push_back(recv_ptr); } ls->wait_processing_pack_queue_.clear(); ls->wait_processing_pack_queue_lock_.Unlock(); for(itr = tmp_list.begin(); itr != tmp_list.end(); ++itr) { recv_ptr = *itr; ls->push_free_processing_pack(recv_ptr); } tmp_list.clear(); } AfxEndThread(0); return 0; }
int CPcpThread::ExitInstance() { if (m_pMainWnd != NULL) { m_lpMainWnd->DestroyWindow(); delete m_lpMainWnd; m_lpMainWnd = NULL; m_pMainWnd = NULL; } m_lpThis = NULL; OleUninitialize(); EmptyWorkingSet(GetCurrentProcess()); CHooks::UnHook(); CWinThread::ExitInstance(); AfxEndThread(0); return 0; }
BOOL CALLBACK InstallCallback(DWORD dwCode, DWORD dwProgress, LPCTSTR lpszMsg, void *cookie) { HWND hMainWnd = (HWND)cookie; if( PROG_PROGRESS == dwCode && ::IsWindow(hMainWnd) ) { ::SendMessage( hMainWnd, WM_USER_INSTALL_PROGRESS, dwProgress, (LPARAM)lpszMsg ); } else if( ::IsWindow(hMainWnd) ) { ::SendMessage( hMainWnd, WM_USER_INSTALL_MESSAGE, dwCode, (LPARAM)lpszMsg ); } // User wants to quit program if(WAIT_OBJECT_0 == WaitForSingleObject(CInstallPacDlg::m_hEventKillInstallThread,0) ) { ::PostMessage( hMainWnd, WM_USER_INSTALL_END, FALSE, 0 ); SetEvent(CInstallPacDlg::m_hEventInstallThreadKilled); AfxEndThread( 0, TRUE ); return FALSE; } return TRUE; }
// // The CommThread Function. // UINT CSerialPort::CommThread(LPVOID pParam) { // Cast the void pointer passed to the thread back to // a pointer of CSerialPort class CSerialPort *port = (CSerialPort*)pParam; // Set the status variable in the dialog class to // TRUE to indicate the thread is running. port->m_bThreadAlive = TRUE; // Misc. variables DWORD BytesTransfered = 0; DWORD Event = 0; DWORD CommEvent = 0; DWORD dwError = 0; static COMSTAT comstat; BOOL bResult = TRUE; // Clear comm buffers at startup if (port->m_hComm) // check if the port is opened PurgeComm(port->m_hComm, PURGE_RXCLEAR | PURGE_TXCLEAR | PURGE_RXABORT | PURGE_TXABORT); // begin forever loop. This loop will run as long as the thread is alive. for (;;) { // Make a call to WaitCommEvent(). This call will return immediatly // because our port was created as an async port (FILE_FLAG_OVERLAPPED // and an m_OverlappedStructerlapped structure specified). This call will cause the // m_OverlappedStructerlapped element m_OverlappedStruct.hEvent, which is part of the m_hEventArray to // be placed in a non-signeled state if there are no bytes available to be read, // or to a signeled state if there are bytes available. If this event handle // is set to the non-signeled state, it will be set to signeled when a // character arrives at the port. // we do this for each port! bResult = WaitCommEvent(port->m_hComm, &Event, &port->m_ov); if (!bResult) { // If WaitCommEvent() returns FALSE, process the last error to determin // the reason.. switch (dwError = GetLastError()) { case ERROR_IO_PENDING: { // This is a normal return value if there are no bytes // to read at the port. // Do nothing and continue break; } case 87: { // Under Windows NT, this value is returned for some reason. // I have not investigated why, but it is also a valid reply // Also do nothing and continue. break; } default: { // All other error codes indicate a serious error has // occured. Process this error. port->ProcessErrorMessage("WaitCommEvent()"); break; } } } else { // If WaitCommEvent() returns TRUE, check to be sure there are // actually bytes in the buffer to read. // // If you are reading more than one byte at a time from the buffer // (which this program does not do) you will have the situation occur // where the first byte to arrive will cause the WaitForMultipleObjects() // function to stop waiting. The WaitForMultipleObjects() function // resets the event handle in m_OverlappedStruct.hEvent to the non-signelead state // as it returns. // // If in the time between the reset of this event and the call to // ReadFile() more bytes arrive, the m_OverlappedStruct.hEvent handle will be set again // to the signeled state. When the call to ReadFile() occurs, it will // read all of the bytes from the buffer, and the program will // loop back around to WaitCommEvent(). // // At this point you will be in the situation where m_OverlappedStruct.hEvent is set, // but there are no bytes available to read. If you proceed and call // ReadFile(), it will return immediatly due to the async port setup, but // GetOverlappedResults() will not return until the next character arrives. // // It is not desirable for the GetOverlappedResults() function to be in // this state. The thread shutdown event (event 0) and the WriteFile() // event (Event2) will not work if the thread is blocked by GetOverlappedResults(). // // The solution to this is to check the buffer with a call to ClearCommError(). // This call will reset the event handle, and if there are no bytes to read // we can loop back through WaitCommEvent() again, then proceed. // If there are really bytes to read, do nothing and proceed. bResult = ClearCommError(port->m_hComm, &dwError, &comstat); if (comstat.cbInQue == 0) continue; } // end if bResult // Main wait function. This function will normally block the thread // until one of nine events occur that require action. Event = WaitForMultipleObjects(3, port->m_hEventArray, FALSE, INFINITE); switch (Event) { case 0: { // Shutdown event. This is event zero so it will be // the higest priority and be serviced first. port->m_bThreadAlive = FALSE; // Kill this thread. break is not needed, but makes me feel better. AfxEndThread(100); break; } case 1: // read event { GetCommMask(port->m_hComm, &CommEvent); if (CommEvent & EV_CTS) ::SendMessage(port->m_pOwner->m_hWnd, WM_COMM_CTS_DETECTED, (WPARAM) 0, (LPARAM) port->m_nPortNr); if (CommEvent & EV_RXFLAG) ::SendMessage(port->m_pOwner->m_hWnd, WM_COMM_RXFLAG_DETECTED, (WPARAM) 0, (LPARAM) port->m_nPortNr); if (CommEvent & EV_BREAK) ::SendMessage(port->m_pOwner->m_hWnd, WM_COMM_BREAK_DETECTED, (WPARAM) 0, (LPARAM) port->m_nPortNr); if (CommEvent & EV_ERR) ::SendMessage(port->m_pOwner->m_hWnd, WM_COMM_ERR_DETECTED, (WPARAM) 0, (LPARAM) port->m_nPortNr); if (CommEvent & EV_RING) ::SendMessage(port->m_pOwner->m_hWnd, WM_COMM_RING_DETECTED, (WPARAM) 0, (LPARAM) port->m_nPortNr); if (CommEvent & EV_RXCHAR) // Receive character event from port. ReceiveChar(port, comstat); break; } case 2: // write event { // Write character event from port WriteChar(port); break; } } // end switch } // close forever loop return 0; }