bool EClientSocket::eConnect( const char *host, UINT port, int clientId) { // already connected? if( isConnected()) { getWrapper()->error( NO_VALID_ID, ALREADY_CONNECTED.code(), ALREADY_CONNECTED.msg()); return false; } // init sockets AfxSocketInit(); // close open connection if there was one eDisconnect(); // create socket m_pSocket.reset(new MySocket(this)); if( !m_pSocket->Create()) { eDisconnect(); getWrapper()->winError( "Failed to create socket", GetLastError() ); getWrapper()->error( NO_VALID_ID, FAIL_CREATE_SOCK.code(), FAIL_CREATE_SOCK.msg()); return false; } // use local machine if no host passed in if( !(host && *host)) { host = "127.0.0.1"; } // connect to server if( !m_pSocket->Connect(host, port)) { int lastError = GetLastError(); if( lastError != WSAEWOULDBLOCK && !handleSocketError(GetLastError())) { return false; } } setClientId( clientId); { // Wait till we are fully connected (or for an error) CWinThread* pThread = AfxGetThread(); while( m_pSocket.get() && !isConnected()) { if (!pThread->PumpMessage()) return false; } } return true; }
/* ================= RadiantInit This is also called when you 'quit' in doom ================= */ void RadiantInit( void ) { // make sure the renderer is initialized if ( !renderSystem->IsOpenGLRunning() ) { common->Printf( "no OpenGL running\n" ); return; } g_editorAlive = true; // allocate a renderWorld and a soundWorld if ( g_qeglobals.rw == NULL ) { g_qeglobals.rw = renderSystem->AllocRenderWorld(); g_qeglobals.rw->InitFromMap( NULL ); } if ( g_qeglobals.sw == NULL ) { g_qeglobals.sw = soundSystem->AllocSoundWorld( g_qeglobals.rw ); } if ( g_DoomInstance ) { if ( ::IsWindowVisible( win32.hWnd ) ) { ::ShowWindow( win32.hWnd, SW_HIDE ); g_pParentWnd->ShowWindow( SW_SHOW ); g_pParentWnd->SetFocus(); } } else { Sys_GrabMouseCursor( false ); g_DoomInstance = win32.hInstance; CWinApp* pApp = AfxGetApp(); CWinThread *pThread = AfxGetThread(); InitAfx(); // App global initializations (rare) pApp->InitApplication(); // Perform specific initializations pThread->InitInstance(); qglFinish(); //qwglMakeCurrent(0, 0); qwglMakeCurrent(win32.hDC, win32.hGLRC); // hide the doom window by default ::ShowWindow( win32.hWnd, SW_HIDE ); } }
BOOL CDialog::OnCmdMsg(UINT nID, int nCode, void* pExtra, AFX_CMDHANDLERINFO* pHandlerInfo) { if (CWnd::OnCmdMsg(nID, nCode, pExtra, pHandlerInfo)) return TRUE; if ((nCode != CN_COMMAND && nCode != CN_UPDATE_COMMAND_UI) || !IS_COMMAND_ID(nID) || nID >= 0xf000) { // control notification or non-command button or system command return FALSE; // not routed any further } // if we have an owner window, give it second crack CWnd* pOwner = GetParent(); if (pOwner != NULL) { #ifdef _DEBUG if (afxTraceFlags & traceCmdRouting) TRACE1("Routing command id 0x%04X to owner window.\n", nID); #endif ASSERT(pOwner != this); if (pOwner->OnCmdMsg(nID, nCode, pExtra, pHandlerInfo)) return TRUE; } // last crack goes to the current CWinThread object CWinThread* pThread = AfxGetThread(); if (pThread != NULL) { #ifdef _DEBUG if (afxTraceFlags & traceCmdRouting) TRACE1("Routing command id 0x%04X to app.\n", nID); #endif if (pThread->OnCmdMsg(nID, nCode, pExtra, pHandlerInfo)) return TRUE; } #ifdef _DEBUG if (afxTraceFlags & traceCmdRouting) { TRACE2("IGNORING command id 0x%04X sent to %hs dialog.\n", nID, GetRuntimeClass()->m_lpszClassName); } #endif return FALSE; }
// @pymethod |PyCWinThread|CreateThread|Creates the actual thread behind the thread object. static PyObject * ui_thread_create_thread(PyObject *self, PyObject *args) { DWORD createFlags = 0; UINT stackSize = 0; if (!PyArg_ParseTuple(args, "|li:CreateThread", &createFlags, &stackSize)) return NULL; CWinThread *pThread = GetCWinThreadPtr(self); if (!pThread) return NULL; PyEval_InitThreads(); GUI_BGN_SAVE; BOOL ok = pThread->CreateThread(createFlags, stackSize); GUI_END_SAVE; if (!ok) RETURN_ERR("CreateThread failed"); RETURN_NONE; }
//-------------------------------------------------------------------------------- int CThreadPool::ExitInstance() { MSG msg; while(PeekMessage(&msg, (HWND) -1, TPMSG_MESSAGE, TPMSG_MESSAGE, PM_REMOVE)) delete (CThreadPoolMsg*) msg.wParam; CSingleLock lock(&m_waiting.m_mutex, false); if(! lock.Lock(INFINITE)) return -1; CSingleLock lock2(&m_active.m_mutex, false); if(! lock2.Lock(INFINITE)) return -1; // stop all threads // wait for them to exit int nSizeA = m_active.GetCount(); int nSizeW = m_waiting.GetCount(); int nSize = nSizeA + nSizeW; if(nSize > 0) { POSITION pos = m_active.GetHeadPosition(); HANDLE* pHands = new HANDLE[nSize]; CWinThread* pThread = NULL; for(int i = 0; i < nSizeA; i++) { pThread = m_active.GetNext(pos); pHands[i] = pThread->m_hThread; pThread->PostThreadMessage(WM_QUIT, 0, 0); } pos = m_waiting.GetHeadPosition(); for(; i < nSize; i++) { pThread = m_waiting.GetNext(pos); pHands[i] = pThread->m_hThread; pThread->PostThreadMessage(WM_QUIT, 0, 0); } ::WaitForMultipleObjects(nSize, pHands, true, 60000); } return CWinThread::ExitInstance(); }
//-------------------------------------------------------------------------------- void CThreadPool::DoMsg(WPARAM wMsg, LPARAM) { // attempt to move a thread from waiting to active, then send it the msg // if there are no avail waiting threads, then keep sending ourselves the msg // until a thread becomes available CThreadPoolMsg* pMsg = (CThreadPoolMsg*) wMsg; CWinThread* pThread = GetNextWaiting(); if(pThread == NULL) { ::Sleep(20); PostThreadMessage(TPMSG_MESSAGE, (WPARAM) pMsg, 0); return; } SetThreadActive(pThread); pThread->PostThreadMessage(pMsg->m_nMsg, pMsg->m_wparam, pMsg->m_lparam); delete pMsg; }
// Spawn a thread to a test void ActiveTest::run( CPPUNIT_NS::TestResult *result ) { CWinThread *thread; setTestResult( result ); m_runCompleted.ResetEvent(); thread = ::AfxBeginThread( threadFunction, this, THREAD_PRIORITY_NORMAL, 0, CREATE_SUSPENDED); ::DuplicateHandle( GetCurrentProcess(), thread->m_hThread, GetCurrentProcess(), &m_threadHandle, 0, FALSE, DUPLICATE_SAME_ACCESS ); thread->ResumeThread (); }
/* ================= RadiantInit This is also called when you 'quit' in doom ================= */ void RadiantInit( void ) { // make sure the renderer is initialized if ( !renderSystem->IsOpenGLRunning() ) { common->Printf( "no OpenGL running\n" ); return; } g_editorAlive = true; // allocate a renderWorld and a soundWorld if ( g_qeglobals.rw == NULL ) { // jmarshall // g_qeglobals.defaultEditorMaterial = declManager->FindMaterial( "_editordefault" ); RadiantInitTestWindow(); // jmarshall end g_qeglobals.rw = renderSystem->AllocRenderWorld(); g_qeglobals.rw->InitFromMap( NULL ); } if ( g_qeglobals.sw == NULL ) { g_qeglobals.sw = soundSystem->AllocSoundWorld( g_qeglobals.rw ); } if ( g_DoomInstance ) { if ( ::IsWindowVisible( win32.hWnd ) ) { ::ShowWindow( win32.hWnd, SW_HIDE ); g_pParentWnd->ShowWindow( SW_SHOW ); g_pParentWnd->SetFocus(); } } else { sys->GrabMouseCursor( false ); g_DoomInstance = win32.hInstance; CWinApp* pApp = AfxGetApp(); CWinThread *pThread = AfxGetThread(); InitAfx(); // App global initializations (rare) pApp->InitApplication(); // Perform specific initializations pThread->InitInstance(); qglFinish(); //qwglMakeCurrent(0, 0); renderDevice->BindDeviceToWindow(win32.hDC); // hide the doom window by default ::ShowWindow( win32.hWnd, SW_HIDE ); // jmarshall toolInterfaceLocal.ShowDebugConsole(); // jmarshall end } }
BOOL CSocket::PumpMessages(UINT uStopFlag) { // The same socket better not be blocking in more than one place. ASSERT(m_pbBlocking == NULL); AFX_THREAD_STATE* pThreadState = AfxGetThreadState(); ASSERT(pThreadState->m_hSocketWindow != NULL); BOOL bBlocking = TRUE; m_pbBlocking = &bBlocking; CWinThread* pThread = AfxGetThread(); UINT nTimerID = ::SetTimer(NULL, 0xff00, m_nTimeOut, NULL); if (nTimerID == 0) AfxThrowResourceException(); while (bBlocking) { TRY { MSG msg; if (::PeekMessage(&msg, pThreadState->m_hSocketWindow, WM_SOCKET_NOTIFY, WM_SOCKET_DEAD, PM_REMOVE)) { if (msg.message == WM_SOCKET_NOTIFY && (SOCKET)msg.wParam == m_hSocket) { if (WSAGETSELECTEVENT(msg.lParam) == FD_CLOSE) { break; } if (WSAGETSELECTEVENT(msg.lParam) == uStopFlag) { if (uStopFlag == FD_CONNECT) m_nConnectError = WSAGETSELECTERROR(msg.lParam); break; } } if (msg.wParam != 0 || msg.lParam != 0) CSocket::AuxQueueAdd(msg.message, msg.wParam, msg.lParam); } else if (::PeekMessage(&msg, NULL, WM_TIMER, WM_TIMER, PM_NOREMOVE)) { if (msg.wParam == nTimerID) { ::PeekMessage(&msg, NULL, WM_TIMER, WM_TIMER, PM_REMOVE); break; } } else if (::PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE) && OnMessagePending()) { // allow user-interface updates pThread->OnIdle(-1); } else { // no work to do -- allow CPU to sleep WaitMessage(); } } CATCH_ALL(e) { TRACE0("Error: caught exception in PumpMessage - continuing.\n"); DELETE_EXCEPTION(e); } END_CATCH_ALL } ::KillTimer(NULL, nTimerID); if (!bBlocking) { WSASetLastError(WSAEINTR); return FALSE; } m_pbBlocking = NULL; ::PostMessage(pThreadState->m_hSocketWindow,WM_SOCKET_NOTIFY,0,0); return TRUE; }
UINT AFX_CDECL WebSocketListeningFunc(LPVOID pThis) { DbgSetThreadName("WebSocketListening"); srand(time(NULL)); InitThreadLocale(); SOCKET hSocket = WSASocket(AF_INET, SOCK_STREAM, IPPROTO_TCP, NULL, 0, 0); if (INVALID_SOCKET != hSocket) { SOCKADDR_IN stAddr; stAddr.sin_family = AF_INET; stAddr.sin_port = htons(thePrefs.GetWSPort()); if (thePrefs.GetBindAddrA()) stAddr.sin_addr.S_un.S_addr = inet_addr(thePrefs.GetBindAddrA()); else stAddr.sin_addr.S_un.S_addr = INADDR_ANY; if (!bind(hSocket, (sockaddr*)&stAddr, sizeof(stAddr)) && !listen(hSocket, SOMAXCONN)) { HANDLE hEvent = CreateEvent(NULL, FALSE, TRUE, NULL); if (hEvent) { if (!WSAEventSelect(hSocket, hEvent, FD_ACCEPT)) { HANDLE pWait[] = { hEvent, s_hTerminate }; while (WAIT_OBJECT_0 == WaitForMultipleObjects(2, pWait, FALSE, INFINITE)) { for (;;) { struct sockaddr_in their_addr; int sin_size = sizeof(struct sockaddr_in); SOCKET hAccepted = accept(hSocket,(struct sockaddr *)&their_addr, &sin_size); if (INVALID_SOCKET == hAccepted) break; if (thePrefs.GetAllowedRemoteAccessIPs().GetCount() > 0) { bool bAllowedIP = false; for (int i = 0; i < thePrefs.GetAllowedRemoteAccessIPs().GetCount(); i++) { if (their_addr.sin_addr.S_un.S_addr == thePrefs.GetAllowedRemoteAccessIPs()[i]) { bAllowedIP = true; break; } } if (!bAllowedIP) { LogWarning(_T("Web Interface: Rejected connection attempt from %s"), ipstr(their_addr.sin_addr.S_un.S_addr)); VERIFY( !closesocket(hAccepted) ); break; } } if(thePrefs.GetWSIsEnabled()) { SocketData *pData = new SocketData; pData->hSocket = hAccepted; pData->pThis = pThis; pData->incomingaddr=their_addr.sin_addr; // - do NOT use Windows API 'CreateThread' to create a thread which uses MFC/CRT -> lot of mem leaks! // - 'AfxBeginThread' could be used here, but creates a little too much overhead for our needs. CWinThread* pAcceptThread = new CWinThread(WebSocketAcceptedFunc, (LPVOID)pData); if (!pAcceptThread->CreateThread()) { delete pAcceptThread; pAcceptThread = NULL; VERIFY( !closesocket(hAccepted) ); hAccepted = NULL; } } else { VERIFY( !closesocket(hAccepted) ); hAccepted = NULL; } } } } VERIFY( CloseHandle(hEvent) ); hEvent = NULL; } } VERIFY( !closesocket(hSocket) ); hSocket = NULL; } return 0; }
UINT AFX_CDECL WebSocketListeningFunc(LPVOID pThis) { DbgSetThreadName("WebSocketListening"); srand(time(NULL)); InitThreadLocale(); // WSADATA stData; // if (!WSAStartup(MAKEWORD(1, 1), &stData)) { SOCKET hSocket = WSASocket(AF_INET, SOCK_STREAM, IPPROTO_TCP, NULL, 0, 0); if (INVALID_SOCKET != hSocket) { SOCKADDR_IN stAddr; stAddr.sin_family = AF_INET; stAddr.sin_port = htons(thePrefs.GetWSPort()); stAddr.sin_addr.S_un.S_addr = INADDR_ANY; if (!bind(hSocket, (sockaddr*)&stAddr, sizeof(stAddr)) && !listen(hSocket, SOMAXCONN)) { HANDLE hEvent = CreateEvent(NULL, FALSE, TRUE, NULL); if (hEvent) { if (!WSAEventSelect(hSocket, hEvent, FD_ACCEPT)) { HANDLE pWait[] = { hEvent, s_hTerminate }; while (WAIT_OBJECT_0 == WaitForMultipleObjects(2, pWait, FALSE, INFINITE)) { for (;;) { struct sockaddr_in their_addr; int sin_size = sizeof(struct sockaddr_in); SOCKET hAccepted = accept(hSocket,(struct sockaddr *)&their_addr, &sin_size); if (INVALID_SOCKET == hAccepted) break; if(thePrefs.GetWSIsEnabled()) { SocketData *pData = new SocketData; pData->hSocket = hAccepted; pData->pThis = pThis; pData->incomingaddr=their_addr.sin_addr; // - do NOT use Windows API 'CreateThread' to create a thread which uses MFC/CRT -> lot of mem leaks! // - 'AfxBeginThread' could be used here, but creates a little too much overhead for our needs. CWinThread* pAcceptThread = new CWinThread(WebSocketAcceptedFunc, (LPVOID)pData); if (!pAcceptThread->CreateThread()) { delete pAcceptThread; pAcceptThread = NULL; VERIFY( !closesocket(hSocket) ); } } else VERIFY( !closesocket(hSocket) ); } } } VERIFY( CloseHandle(hEvent) ); } } VERIFY( !closesocket(hSocket) ); } // VERIFY( !WSACleanup() ); } return 0; }
// // Invoke() // // invoke the GIB program and return the recommended play // int CGIB::Invoke(CPlayer* pPlayer, CHandHoldings* pHand, CHandHoldings* pDummyHand, CPlayerStatusDialog* pStatusDlg) { SECURITY_ATTRIBUTES saAttr; // // create the GIB monitor dialog // CGIBDialog gibDialog(pMAINFRAME); int nProcessingTime = theApp.GetValue(tnGIBAnalysisTime); gibDialog.m_nProcessTime = nProcessingTime; // gibDialog.m_hEventCancel = m_hEventCancel; // Set the bInheritHandle flag so pipe handles are inherited. saAttr.nLength = sizeof(SECURITY_ATTRIBUTES); saAttr.bInheritHandle = TRUE; saAttr.lpSecurityDescriptor = NULL; // // create input and output pipes for the child process // // Create a pipe for the child process's STDOUT. if (!CreatePipe(&m_hChildStdoutRd, // returns the pipe's input handle &m_hChildStdoutWr, // returns the pipe's output handle &saAttr, 0)) { CString strError = "Stdout pipe creation failed\n"; TRACE(strError); pMAINFRAME->SetGIBMonitorText(strError); return ExitGracefully(-5); } // then create a pipe for the child process's STDIN. if (!CreatePipe(&m_hChildStdinRd, &m_hChildStdinWr, &saAttr, 0)) { CString strError = "Stdin pipe creation failed\n"; TRACE(strError); pMAINFRAME->SetGIBMonitorText(strError); return ExitGracefully(-5); } // // Now create the child process (GIB) // PROCESS_INFORMATION piProcInfo; if (!LaunchProgram(piProcInfo)) { TRACE("Create process failed"); return ExitGracefully(-1); } HANDLE hGIBProcess = piProcInfo.hProcess; DWORD nGIBProcessID = piProcInfo.dwProcessId; // now close the readable handle to the child's stdin SafeCloseHandle(m_hChildStdinRd); // and the writable handle to the child's stdout SafeCloseHandle(m_hChildStdoutWr); // //------------------------------------------------------------------ // // create the GIB input file // CFile file; CFileException fileException; CString strTempFile, strTempPath; GetTempPath(1024, strTempPath.GetBuffer(1024)); strTempPath.ReleaseBuffer(); GetTempFileName(strTempPath, "ezb", 0, strTempFile.GetBuffer(2048)); strTempFile.ReleaseBuffer(); // strTempFile.Format("%s\\%s", theApp.GetValueString(tszProgramDirectory), tszGIBTempFilename); /* LPTSTR szBuffer = strTempFile.GetBuffer(MAX_PATH); GetTempFileName(theApp.GetValueString(tszProgramDirectory), "ezb", 0, szBuffer); strTempFile.ReleaseBuffer(); */ // CString strInput; // strInput.Format("-T %d %s\n",theApp.GetValue(tnGIBAnalysisTime),strTempFile); int nCode = file.Open(strTempFile, CFile::modeWrite | CFile::modeCreate | CFile::shareDenyWrite, &fileException); if (nCode == 0) { CString strError = "Error opening temporary input file for GIB"; TRACE(strError); pMAINFRAME->SetGIBMonitorText(strError); return ExitGracefully(-2); } // CString strFileContents; CreateGIBInputFile(file, pPlayer, pHand, pDummyHand, strFileContents); file.Close(); // then send the parameters line CString strParameters, strShortParameters; strParameters.Format("-T %d %s\n",nProcessingTime,strTempFile); strShortParameters.Format("-T %d",nProcessingTime); DWORD dwWritten; int nErrCode; if (!WriteFile(m_hChildStdinWr, (LPCTSTR)strParameters, strParameters.GetLength(), &dwWritten, NULL)) { CString strError = "Error providing parameters to GIB"; TRACE(strError); pMAINFRAME->SetGIBMonitorText(strError); nErrCode = GetLastError(); return ExitGracefully(-3); } // // update the GIB monitor window // CString strGIBText = "========================================\n"; strGIBText += FormString("Launching %s %s\n", theApp.GetValueString(tszGIBPath), strShortParameters); // strGIBText += FormString("Input file contents:\n%s", strFileContents); strGIBText += "Awaiting Responses...\n"; strGIBText += "----------------------------------------\n"; // pMAINFRAME->SetGIBMonitorText(strGIBText); pMAINFRAME->AppendGIBMonitorText(strGIBText); // //------------------------------------------------------------ // // now set up the wait loop and the cancel dialog, // then sit and wait for the process to run or for a cancel message // /* // // create the "Cancel GIB" dialog thread // (this is a user interface thread) // CGIBMonitorThread* pMonitorThread = new CGIBMonitorThread(m_hEventFinished, m_hEventCancel, nProcessingTime); pMonitorThread->CreateThread(CREATE_SUSPENDED); pMonitorThread->SetThreadPriority(THREAD_PRIORITY_ABOVE_NORMAL); pMonitorThread->ResumeThread(); // wait for the monitor thread to initialize DWORD nCode0 = WaitForSingleObject(m_hEventFinished, INFINITE); */ // // create the wait thread // (this is a worker thread) // GIBStruct gibData; gibData.hReadHandle = m_hChildStdoutRd; gibData.pGIBDialog = &gibDialog; CWinThread* pWaitThread = AfxBeginThread(CGIB::ReadGIBOutput, &gibData, THREAD_PRIORITY_NORMAL, 0, CREATE_SUSPENDED); // copy its handle se that we can check its exit code later HANDLE hWaitThread; BOOL bCode = ::DuplicateHandle(GetCurrentProcess(), pWaitThread->m_hThread, GetCurrentProcess(), &hWaitThread, 0, FALSE, DUPLICATE_SAME_ACCESS); // and launch the threads // MonitorThread->ResumeThread(); pWaitThread->ResumeThread(); // // Show the Wait/Cancel dialog // m_bGIBPending = TRUE; // mark dialog as active bCode = gibDialog.DoModal(); // see if the user cancelled if (!bCode) { /* // lock out the wait thread and cancel operations if (ClearGIBPending()) { */ // pMAINFRAME->SetStatusText("GIB cancelled."); // TerminateProcess(hGIBProcess, 0); TerminateThread(hWaitThread, 0); // wait for the read thread to end WaitForSingleObject(hWaitThread, INFINITE); // close the wait thread handle CloseHandle(hWaitThread); CloseHandle(hGIBProcess); // and delete the thread object delete pWaitThread; // close pipe handles SafeCloseHandle(m_hChildStdinWr); SafeCloseHandle(m_hChildStdoutRd); // and throw an exception throw CGIBException(); // } } /* // set up events HANDLE eventArray[2]; eventArray[0] = m_hEventCancel; eventArray[1] = pWaitThread->m_hThread; // // then sit back and wait for the thread(s) // for(;;) { // wait for the cancelled or finished messages DWORD nCode = WaitForMultipleObjects(2, // 2 events to wait for eventArray, // events array FALSE, // not all at once INFINITE); // wait 4-ever // if (nCode == WAIT_FAILED) { ASSERT(FALSE); break; } else if (nCode == WAIT_OBJECT_0) { // got the cancel message, so kill GIB & the wait thread // the following is very dangersous -- // so kids, don't try this at home TerminateThread(pWaitThread, 0); TerminateProcess(hGIBProcess, 0); return GIB_CANCEL; } else if (nCode == WAIT_OBJECT_0 + 1) { // GIB finished message // signal the GIB monitor that GIB has finished SetEvent(m_hEventFinished); break; } } */ // //------------------------------------------------------------ // // presumably, GIB has finished running // // wait for the GIB thread to exit, then get the card code DWORD nCardPlayed, nErrorCode; bCode = WaitForSingleObject(hWaitThread, INFINITE); bCode = GetExitCodeThread(hWaitThread, &nCardPlayed); if (!bCode) nErrorCode = GetLastError(); // close the wait thread handle CloseHandle(hWaitThread); // delete the temporary file DeleteFile(strTempFile); // and kill the child process // first send a Ctrl-C to the app // (this doesn't seem to do anything) CString strInput = "\03"; // Ctrl-C if (!WriteFile(m_hChildStdinWr, (LPCTSTR)strInput, strInput.GetLength(), &dwWritten, NULL)) { CString strError = "Error stopping GIB"; TRACE(strError); pMAINFRAME->SetGIBMonitorText(strError); nErrCode = GetLastError(); return ExitGracefully(-4); } // close the writable handle to the child's stdin SafeCloseHandle(m_hChildStdinWr); // then call terminateProcess TerminateProcess(hGIBProcess, 0); CloseHandle(hGIBProcess); // then close the readable handle to the child's stdout SafeCloseHandle(m_hChildStdoutRd); // // done // return nCardPlayed; }
void CChatControl::GetConnect() { // Test for internet connection if(!m_autPrefs->GetLanMode() && !m_InetTested) { CWinThread* pThread = AfxBeginThread(TestInetThread, this, THREAD_PRIORITY_NORMAL, 0, CREATE_SUSPENDED); AssignThreadToCPU(pThread, CPU_0); pThread->ResumeThread(); return; } if(m_autPrefs->GetLanMode()) { if(m_pPrefs->m_InternalIRC) { CString Host = m_pPrefs->m_InternalIRCAddr; int pos = Host.Find(":"); if(pos != -1) AddServer( Host.Left(Host.Find(":")), atoi(Host.Mid(Host.Find(":") + 1))); else AddServer(m_pPrefs->m_InternalIRCAddr, 6667); } return; } // If its for chat if(m_pDoc->m_pViewChat) if(m_pPrefs->m_PrefNet == "GnuDefault") { AddServer("irc.freenode.net", 6667); return; } // Connect to random server on default network for(int i = 0; i < m_pPrefs->m_ChatNets.size(); i++) if(m_pPrefs->m_ChatNets[i].Name == m_pPrefs->m_PrefNet) if(m_pPrefs->m_ChatNets[i].Servers.size()) { int servpos = rand() % m_pPrefs->m_ChatNets[i].Servers.size() + 0; CString Parse = m_pPrefs->m_ChatNets[i].Servers[servpos]; // Take first server from list, and move it to the back //pPrefs->m_ChatNets[i].Servers.erase( pPrefs->m_ChatNets[i].Servers.begin() ); //pPrefs->m_ChatNets[i].Servers.push_back(Parse); int colon = Parse.Find( _T(":") ); if(colon != -1) { std::vector<UINT> PortList; CString Server = Parse.Left(colon); CString PortString = Parse.Mid(colon + 1) + ","; int pos = 0; while(PortString.Find( _T(","), pos) != -1) { UINT port = atoi(PortString.Mid(pos, PortString.Find( _T(","), pos) - pos)); PortList.push_back(port); pos = PortString.Find( _T(","), pos) + 1; } if(PortList.size()) { int portpos = rand() % PortList.size() + 0; AddServer(Server, PortList[portpos]); return; } } } }
///// // 主工作线程 // 功能:从数据库表 skucode_t 中读出要查询的货号,分配给子工作线程进行计算 UINT AFX_CDECL MainWorkThreadFunc(LPVOID *lpParam) { ASSERT(lpParam != NULL); BOOL bRet = FALSE; MYSQL_ROW row = NULL; LPMAINWORKTHREADPARAM pParam = (LPMAINWORKTHREADPARAM) lpParam; CMPSCore Core; AfxGetApp()->GetMainWnd()->PostMessageA( WM_USER_UI_UPDATE_PROCESS, (WPARAM) RESET_PROCESS, (LPARAM) 0); // 连接数据库 bRet = Core.ConnectDB("127.0.0.1", "root", "", "test", 0, NULL, 0); // 子进程会添加记录到数据库中,应在此先清空该表 if (bRet) { CString SQL, TableName; CMPSCore::GenerateTableName(pParam->_StartingDate, pParam->_FirstWeekSale, TableName); SQL.Format("TRUNCATE TABLE `%s`", (LPCTSTR)TableName); bRet = Core.NonSelectQuery(SQL); } // 准备所有SKUCODE的集合 // Map key: SkuCode // Map value: Sub SkuCode std::multimap <std::string, std::string> SkuCodeMap; if (bRet) { bRet = Core.SelectQuery( "select indexcode, mapping1, mapping2, mapping3, mapping4, mapping5, mapping6, mapping7 from skuinfo"); } if (bRet) { while (row = Core.GetRecord(), row != NULL) { BOOL bIncludeSelf = FALSE; if (IS_EMPTY(row[0])) continue; for (int i=1; i<=7; i++) { if (IS_EMPTY(row[i])) continue; SkuCodeMap.insert(std::pair<std::string,std::string>(row[0],row[i])); if ( strcmp(row[0], row[i]) == 0 ) bIncludeSelf = TRUE; } if (!bIncludeSelf) SkuCodeMap.insert(std::pair<std::string,std::string>(row[0],row[0])); } Core.FreeRecord(); } // 计数器和记录的总数,用于显示在UI上 UINT nCount = 0; UINT nAmount = 0; nAmount = SkuCodeMap.size(); if (bRet) { std::multimap<std::string,std::string>::iterator it; CString SQL; for ( it = SkuCodeMap.begin() ; bRet && it != SkuCodeMap.end(); it++ ) { ////////////////////////////////////////////////////////////////////////// // 刷新UI上的进度 ////////////////////////////////////////////////////////////////////////// nCount++; AfxGetApp()->GetMainWnd()->PostMessageA( WM_USER_UI_UPDATE_PROCESS, (WPARAM) UPDATE_PROCESS, (LPARAM) ((nAmount << 16) | nCount)); ////////////////////////////////////////////////////////////////////////// SQL.Format("select DISTINCT(`jdewh`) from `openinv_o` where `jdeskucode`='%s'", it->second.c_str()); bRet = Core.SelectQuery((LPCTSTR)SQL); if ( !bRet ) break; while ( row = Core.GetRecord(), row != NULL) { #ifdef _DEBUG if (nCount > 50) break; #endif if (IS_EMPTY(row[0])) continue; // 等待子工作线程资源(设置了同时工作的子线程数上限) if (WaitForSingleObject((HANDLE)gSubThreadCount, INFINITE) != WAIT_OBJECT_0) { // 异常结束 bRet = FALSE; break; } else { LPSUBWORKTHREADPARAM lpSubThreadParam = new SUBWORKTHREADPARAM; CWinThread *pWinThread = NULL; // 准备子工作线程的参数 lpSubThreadParam->_StartingDate = pParam->_StartingDate; lpSubThreadParam->_FirstWeekSale = pParam->_FirstWeekSale; strcpy_s(lpSubThreadParam->_ParentSkuCode, it->first.c_str()); strcpy_s(lpSubThreadParam->_SkuCode, it->second.c_str()); strcpy_s(lpSubThreadParam->_WareHouse, row[0]); // 启动一个子工作线程 pWinThread = AfxBeginThread((AFX_THREADPROC)SubWorkThreadFunc, (LPVOID)lpSubThreadParam, THREAD_PRIORITY_NORMAL, 0, CREATE_SUSPENDED); pWinThread->m_bAutoDelete = TRUE; pWinThread->ResumeThread(); } } Core.FreeRecord(); } } AfxGetApp()->GetMainWnd()->PostMessageA( WM_USER_UI_UPDATE_PROCESS, (WPARAM) END_PROCESS, (LPARAM) ((nAmount << 16) | nCount)); //TODO: 需等待子线程结束? delete pParam; return 0; }