Eina_Bool ecore_con_local_listen(Ecore_Con_Server *svr) { char buf[256]; HANDLE thread_listening; Ecore_Win32_Handler *handler; if ((svr->type & ECORE_CON_TYPE) == ECORE_CON_LOCAL_ABSTRACT) { ERR("Your system does not support abstract sockets!"); return EINA_FALSE; } if ((svr->type & ECORE_CON_TYPE) == ECORE_CON_LOCAL_USER) snprintf(buf, sizeof(buf), "\\\\.\\pipe\\%s", svr->name); else if ((svr->type & ECORE_CON_TYPE) == ECORE_CON_LOCAL_SYSTEM) { const char *computername; computername = getenv("CoMPUTERNAME"); snprintf(buf, sizeof(buf), "\\\\%s\\pipe\\%s", computername, svr->name); } svr->path = strdup(buf); if (!svr->path) { ERR("Allocation failed"); return EINA_FALSE; } /* * synchronuous * block mode * wait mode */ svr->pipe = CreateNamedPipe(svr->path, PIPE_ACCESS_DUPLEX, PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE | PIPE_WAIT, PIPE_UNLIMITED_INSTANCES, BUFSIZE, BUFSIZE, 5000, NULL); if (svr->pipe == INVALID_HANDLE_VALUE) { ERR("Creation of the named pipe failed"); goto free_path; } /* * We use ConnectNamedPipe() to wait for a client to connect. * As the function is blocking, to let the main loop continuing * its iterations, we call ConnectNamedPipe() in a thread */ thread_listening = (HANDLE)_beginthreadex(NULL, 0, _ecore_con_local_win32_listening, svr, CREATE_SUSPENDED, NULL); if (!thread_listening) { ERR("Creation of the listening thread failed"); goto close_pipe; } handler = ecore_main_win32_handler_add(thread_listening, _ecore_con_local_win32_client_add, svr); if (!handler) { ERR("Creation of the client add handler failed"); goto del_handler; } svr->read_stopped = EINA_TRUE; ResumeThread(thread_listening); return EINA_TRUE; del_handler: ecore_main_win32_handler_del(handler); close_pipe: CloseHandle(svr->pipe); free_path: free(svr->path); svr->path = NULL; return EINA_FALSE; }
int main() { int failed = 0; int i; HANDLE h[NUMTHREADS + 1]; for (i = 1; i <= NUMTHREADS; i++) { threadbag[i].started = 0; threadbag[i].threadnum = i; #if ! defined (__MINGW32__) || defined (__MSVCRT__) h[i] = (HANDLE) _beginthreadex(NULL, 0, Win32thread, (void *) &threadbag[i], 0, NULL); #else h[i] = (HANDLE) _beginthread(Win32thread, 0, (void *) &threadbag[i]); #endif } /* * Code to control or munipulate child threads should probably go here. */ Sleep(500); /* * Cancel all threads. */ for (i = 1; i <= NUMTHREADS; i++) { assert(pthread_kill(threadbag[i].self, 0) == 0); assert(pthread_cancel(threadbag[i].self) == 0); } /* * Give threads time to run. */ Sleep(NUMTHREADS * 100); /* * Standard check that all threads started. */ for (i = 1; i <= NUMTHREADS; i++) { if (!threadbag[i].started) { failed |= !threadbag[i].started; fprintf(stderr, "Thread %d: started %d\n", i, threadbag[i].started); } } assert(!failed); /* * Check any results here. Set "failed" and only print output on failure. */ failed = 0; for (i = 1; i <= NUMTHREADS; i++) { int fail = 0; int result = 0; #if ! defined (__MINGW32__) || defined (__MSVCRT__) assert(GetExitCodeThread(h[i], (LPDWORD) &result) == TRUE); #else /* * Can't get a result code. */ result = (int) PTHREAD_CANCELED; #endif assert(threadbag[i].self != NULL); assert(pthread_kill(threadbag[i].self, 0) == ESRCH); fail = (result != (int) PTHREAD_CANCELED); if (fail) { fprintf(stderr, "Thread %d: started %d: count %d\n", i, threadbag[i].started, threadbag[i].count); } failed = (failed || fail); } assert(!failed); /* * Success. */ return 0; }
bool CWinRunnerThread::Start(IThread* aObj) { mHandleThread = (HANDLE)_beginthreadex(NULL, 0, (CWinRunnerThread::func_runner), (void*)aObj, 0, NULL); return mHandleThread != 0; }
void main() { LINKEDLIST LogInlist; LogInlist.InitList = InitLinkedList; LogInlist.InitList(&LogInlist, AddTop, AddBottom, AddPoint, DeleteAt, DeleteTop, DeleteBottom, DeleteAll); LINKEDLIST Memberlist; Memberlist.InitList = InitLinkedList; Memberlist.InitList(&Memberlist, AddTop, AddBottom, AddPoint, DeleteAt, DeleteTop, DeleteBottom, DeleteAll); LINKEDLIST Videolist; Videolist.InitList = InitLinkedList; Videolist.InitList(&Videolist, AddTop, AddBottom, AddPoint, DeleteAt, DeleteTop, DeleteBottom, DeleteAll); LINKEDLIST Rentallist; Rentallist.InitList = InitLinkedList; Rentallist.InitList(&Rentallist, AddTop, AddBottom, AddPoint, DeleteAt, DeleteTop, DeleteBottom, DeleteAll); LINKEDLIST pSameNameRenTalList; pSameNameRenTalList.InitList = InitLinkedList; pSameNameRenTalList.InitList(&pSameNameRenTalList, AddTop, AddBottom, AddPoint, DeleteAt, DeleteTop, DeleteBottom, DeleteAll); File_Read_Member(&Memberlist); File_Read_Video(&Videolist); File_Read_Rental(&Rentallist); LINKEDLIST list; memset(&list, 0, sizeof(list)); WSADATA data; memset(&data, 0, sizeof(data)); WSAStartup(MAKEWORD(2, 2), &data); SOCKET ServerSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); if (ServerSocket == INVALID_SOCKET) { printf("ServerSocket 생성실패"); return; } SOCKADDR_IN addr; memset(&addr, 0, sizeof(addr)); addr.sin_addr.s_addr = INADDR_ANY; addr.sin_family = AF_INET; addr.sin_port = htons(50000); int iError = bind(ServerSocket, (sockaddr*)&addr, sizeof(addr)); if (iError == SOCKET_ERROR) { printf("BIND ERROR\n"); return; } iError = listen(ServerSocket, SOMAXCONN); if (iError == SOCKET_ERROR) { printf("LISTEN ERROR\n"); return; } THREADPARAM AcceptParam; memset(&AcceptParam, 0, sizeof(AcceptParam)); AcceptParam.pLinkedList = &list; AcceptParam.pMemberLIst = &Memberlist; AcceptParam.pVideoList = &Videolist; AcceptParam.pRenTalList = &Rentallist; AcceptParam.pLogInList = &LogInlist; AcceptParam.pSameNameRenTalList = &pSameNameRenTalList; AcceptParam.Socket = ServerSocket; _beginthreadex(NULL, NULL, AcceptFunc, (void*)&AcceptParam, NULL, NULL); int iChoice = 1; int iManageMamber = 1; int iManageVideo = 1; int iManageRental = 1; char temp[128]; while (iChoice != 0) //메인 루프 { printf("1. 회원 관리 2. 비디오 관리 3. 비디오 대여 목록 관리 9.서버종료 \n"); scanf_s("%d", &iChoice); fflush(stdin); switch (iChoice) { case 1: while (iManageMamber != 0) { printf("1. 접속자 관리 \n"); printf("1.회원 추가 2. 회원 목록 3. 회원 검색 4. 회원 수정 5.회원 삭제 0.메인메뉴 \n"); scanf_s("%d", &iManageMamber); fflush(stdin); switch (iManageMamber) { case 1: InputMember_Server(&Memberlist, &LogInlist); break; case 2: vPrintMember(&Memberlist); break; case 3: SearchMember(&Memberlist); break; case 4: ModifyMember_Server(&Memberlist); break; case 5: DeleteMember_Server(&Memberlist); break; case 6: iManageMamber = 0; break; } printf("\n"); } iManageMamber = 1; break; case 2: while (iManageVideo != 0) { printf("2. 비디오 관리 \n"); printf("1.비디오추가 2. 비디오 목록 3.비디오 검색 4. 비디오 수정 5. 비디오 삭제 0.메인메뉴\n"); scanf_s("%d", &iManageVideo); fflush(stdin); switch (iManageVideo) { case 1: InputVideo(&Videolist); break; case 2: vPrintVideo(&Videolist); break; case 3: SearchVideo(&Videolist); break; case 4: ModifyVideo(&Videolist); break; case 5: DeleteVideo(&Videolist); break; case 0: iManageVideo = 0; break; } printf("\n"); } iManageVideo = 1; break; case 3: while (iManageRental !=0) { printf("3. 비디오 대여관리\n1 = 비디오 대여 , 2 = 비디오 반납 , 3 = 비디오 대여목록 4 = 회원 대여목록 검색,0 =메인메뉴\n"); scanf_s("%d", &iManageRental); fflush(stdin); switch (iManageRental){ case 1: InputRental_Server(&Memberlist, &Videolist, &Rentallist); break; case 2: ReturnVideo(&Rentallist,&Videolist); break; case 3: PrintRentallist(&Rentallist); break; case 4: printf("찾을 회원의 이름 \n"); gets_s(temp, sizeof(temp)); fflush(stdin); PrintMemberRentalList(&Rentallist,temp); break; case 0: iManageRental = 0; break; } printf("\n"); } iManageRental = 1; break; case 9: iChoice = 0; break; } File_Write_Member(&Memberlist); File_Write_Video(&Videolist); File_Write_Rental(&Rentallist); } //메인루프 끝 closesocket(ServerSocket); WSACleanup(); }
//////////////////////////////////////////////////////////////////////////////// // // FUNCTION: CIOCPServer::ThreadPoolFunc // // DESCRIPTION: This is the main worker routine for the worker threads. // Worker threads wait on a completion port for I/O to complete. // When it completes, the worker thread processes the I/O, then either pends // new I/O or closes the client's connection. When the service shuts // down, other code closes the completion port which causes // GetQueuedCompletionStatus() to wake up and the worker thread then // exits. // // INPUTS: // // NOTES: // // MODIFICATIONS: // // Name Date Version Comments // N T ALMOND 06042001 1.0 Origin // Ulf Hedlund 09062001 Changes for OVERLAPPEDPLUS //////////////////////////////////////////////////////////////////////////////// unsigned CIOCPServer::ThreadPoolFunc (LPVOID thisContext) { // Get back our pointer to the class ULONG ulFlags = MSG_PARTIAL; CIOCPServer* pThis = reinterpret_cast<CIOCPServer*>(thisContext); ASSERT(pThis); HANDLE hCompletionPort = pThis->m_hCompletionPort; DWORD dwIoSize; LPOVERLAPPED lpOverlapped; ClientContext* lpClientContext; OVERLAPPEDPLUS* pOverlapPlus; bool bError; bool bEnterRead; InterlockedIncrement(&pThis->m_nCurrentThreads); InterlockedIncrement(&pThis->m_nBusyThreads); // // Loop round and round servicing I/O completions. // for (BOOL bStayInPool = TRUE; bStayInPool && pThis->m_bTimeToKill == false; ) { pOverlapPlus = NULL; lpClientContext = NULL; bError = false; bEnterRead = false; // Thread is Block waiting for IO completion InterlockedDecrement(&pThis->m_nBusyThreads); // Get a completed IO request. BOOL bIORet = GetQueuedCompletionStatus( hCompletionPort, &dwIoSize, (LPDWORD) &lpClientContext, &lpOverlapped, INFINITE); DWORD dwIOError = GetLastError(); pOverlapPlus = CONTAINING_RECORD(lpOverlapped, OVERLAPPEDPLUS, m_ol); int nBusyThreads = InterlockedIncrement(&pThis->m_nBusyThreads); if (!bIORet && dwIOError != WAIT_TIMEOUT ) { if (lpClientContext && pThis->m_bTimeToKill == false) { pThis->RemoveStaleClient(lpClientContext, FALSE); } continue; // anyway, this was an error and we should exit bError = true; } if (!bError) { // Allocate another thread to the thread Pool? if (nBusyThreads == pThis->m_nCurrentThreads) { if (nBusyThreads < pThis->m_nThreadPoolMax) { if (pThis->m_cpu.GetUsage() > pThis->m_nCPUHiThreshold) { UINT nThreadID = -1; HANDLE hThread = (HANDLE)_beginthreadex(NULL, // Security 0, // Stack size - use default ThreadPoolFunc, // Thread fn entry point (void*) pThis, 0, // Init flag &nThreadID); // Thread address CloseHandle(hThread); } } } // Thread timed out - IDLE? if (!bIORet && dwIOError == WAIT_TIMEOUT) { if (lpClientContext == NULL) { if (pThis->m_cpu.GetUsage() < pThis->m_nCPULoThreshold) { // Thread has no outstanding IO - Server hasn't much to do so die if (pThis->m_nCurrentThreads > pThis->m_nThreadPoolMin) bStayInPool = FALSE; } bError = true; } } } ////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////// if (!bError) { if(bIORet && NULL != pOverlapPlus && NULL != lpClientContext) { try { pThis->ProcessIOMessage(pOverlapPlus->m_ioType, lpClientContext, dwIoSize); } catch (...) {} } } if(pOverlapPlus) delete pOverlapPlus; // from previous call } InterlockedDecrement(&pThis->m_nWorkerCnt); InterlockedDecrement(&pThis->m_nCurrentThreads); InterlockedDecrement(&pThis->m_nBusyThreads); return 0; }
void testNonACEThread () { ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("Beginning non-ACE thread lookup test\n"))); static const ACE_TCHAR *svc_desc = #if (ACE_USES_CLASSIC_SVC_CONF == 1) ACE_TEXT ("dynamic Test_Object_1_Thr Service_Object * ") ACE_TEXT (" Service_Config_DLL:_make_Service_Config_DLL() \"Test_Object_1_Thr\"") #else ACE_TEXT ("<dynamic id=\"Test_Object_1_Thr\" type=\"Service_Object\">") ACE_TEXT (" <initializer init=\"_make_Service_Config_DLL\" path=\"Service_Config_DLL\" params=\"Test_Object_1_Thr\"/>") ACE_TEXT ("</dynamic>") #endif /* (ACE_USES_CLASSIC_SVC_CONF == 1) */ ; static const ACE_TCHAR *svc_remove = #if (ACE_USES_CLASSIC_SVC_CONF == 1) ACE_TEXT ("remove Test_Object_1_Thr") #else ACE_TEXT ("<remove id=\"Test_Object_1_Thr\"/>") ACE_TEXT ("</remove>") #endif /* (ACE_USES_CLASSIC_SVC_CONF == 1) */ ; if (-1 == ACE_Service_Config::process_directive (svc_desc)) { ACE_ERROR ((LM_ERROR, ACE_TEXT ("%p\n"), ACE_TEXT ("Error loading service"))); ++error; return; } // Allow the spawned thread to contribute to the logging output. ACE_OS_Log_Msg_Attributes log_msg_attrs; ACE_Log_Msg::init_hook (log_msg_attrs); u_int errors_before = error; #if defined (ACE_HAS_WTHREADS) && !defined (ACE_HAS_WINCE) HANDLE thr_h = (HANDLE)_beginthreadex (0, 0, &nonacethreadentry, &log_msg_attrs, 0, 0); if (thr_h == 0) { ACE_ERROR ((LM_ERROR, ACE_TEXT ("%p\n"), ACE_TEXT ("_beginthreadex"))); ++error; } else { WaitForSingleObject (thr_h, INFINITE); CloseHandle (thr_h); } #elif defined (ACE_HAS_PTHREADS) pthread_t thr_id; int status = pthread_create (&thr_id, 0, nonacethreadentry, &log_msg_attrs); if (status != 0) { errno = status; ACE_ERROR ((LM_ERROR, ACE_TEXT ("%p\n"), ACE_TEXT ("pthread_create"))); ++error; } else { pthread_join (thr_id, 0); } #endif if (error != errors_before) // The test failed; see if we can still see it { if (0 != ACE_Service_Config::instance()->find (ACE_TEXT ("Test_Object_1_Thr"))) { ACE_ERROR ((LM_ERROR, ACE_TEXT ("Main thr %t cannot find Test_Object_1_Thr\n"))); ++error; } else ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("Main thr %t DOES find Test_Object_1_Thr\n"))); } if (-1 == ACE_Service_Config::process_directive (svc_remove)) { ACE_ERROR ((LM_ERROR, ACE_TEXT ("%p\n"), ACE_TEXT ("Error removing service"))); ++error; } else { ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("Non-ACE thread lookup test completed\n"))); } }
LRESULT CALLBACK DlgProc(HWND hDlg_MainProc, UINT Message, WPARAM wParam, LPARAM lParam) { static HWND ButtonCheck = NULL; static HWND EditControl = NULL; static HANDLE handle_Check = NULL; static int PS = 0x22; char EnterText[30] = { 0 }; switch (Message) { case WM_SETCURSOR: if ((DWORD)ButtonCheck == wParam) { if (PS == 0x22) { MoveWindow(ButtonCheck, 10, 10, 80, 35, TRUE); PS = 0x15; } else if (0x15 == PS) { MoveWindow(ButtonCheck, 20, 230, 80, 35, TRUE); PS = 0x18; } else if (0x18 == PS) { MoveWindow(ButtonCheck, 350, 230, 80, 35, TRUE); PS = 0x22; } } break; case WM_COMMAND: if (HIWORD(wParam) == 0) { switch (LOWORD(wParam)) { case IDC_Button1: GetWindowTextA(EditControl, EnterText, 30); //check strlen int x = strlen(EnterText); if (x != 22) { MessageBox(0, L"Try Again", L"Fail", 0); break; } //check HCTF{} if (FALSE == CheckHCTF(EnterText, EnterText[x-1])) { MessageBox(0, L"Try Again", L"Fail", 0); break; } //check——encode if (FALSE == Main_Check(EnterText)) { MessageBox(0, L"Try Again", L"Fail", 0); break; } //馄饨加解密核心 for (int i = 0; i < 100; i++) { int xor = rou^chaos; if (xor > 0)//去掉2个错误情况 { //解密x反作弊flag 亦或比较 if ((EnterText[17] ^ xor) == CHECK_1[0] && (EnterText[18] ^ xor) == CHECK_1[1] && (EnterText[19] ^ xor) == CHECK_1[2] && (EnterText[20] ^ xor) == CHECK_1[3]) { //判断成功进入下一阶段,乱序 int exchange = 0; //0与6换位 exchange = Code1[0]; Code1[0] = Code1[6]; Code1[6] = exchange; //3与8换位 exchange = Code1[3]; Code1[3] = Code1[8]; Code1[8] = exchange; //2与5换位 exchange = Code1[2]; Code1[2] = Code1[5]; Code1[5] = exchange; //11与4换位 exchange = Code1[11]; Code1[11] = Code1[4]; Code1[4] = exchange; //循环进行比较 for (int a = 0; a < 12; a++) { if (Maincjeckaaa[a] != Code1[a]) { MessageBox(0, L"Try Again", L"Fail", 0); exit(-1); } } //最后判断xor是否为2 if (xor != 2) { break; } MessageBox(0, L"YOU GOT IT", L"OK", 0); exit(0); break; } } Sleep(20); } MessageBox(0, L"Try Again", L"Fail", 0); } } break; case WM_INITDIALOG: ButtonCheck = GetDlgItem(hDlg_MainProc, IDC_Button1); EditControl = GetDlgItem(hDlg_MainProc, IDC_EDIT2); //thread1 handle_Check = (HANDLE)_beginthreadex(NULL, 0, Check_ThreadProc, NULL, NULL, NULL); if (NULL == handle_Check) { printf("甜党万岁\n"); } break; case WM_CLOSE: CloseHandle(handle_Check); EndDialog(hDlg_MainProc, 0); DestroyWindow(hDlg_MainProc); break; default: break; } return 0; }
int launch_server(int server_port) { #if defined(_WIN32) /* we need to start the server in the background */ /* we create a PIPE that will be used to wait for the server's "OK" */ /* message since the pipe handles must be inheritable, we use a */ /* security attribute */ SECURITY_ATTRIBUTES sa; sa.nLength = sizeof(sa); sa.lpSecurityDescriptor = NULL; sa.bInheritHandle = TRUE; // Redirect stdin to Windows /dev/null. If we instead pass an original // stdin/stdout/stderr handle and it is a console handle, when the adb // server starts up, the C Runtime will see a console handle for a process // that isn't connected to a console and it will configure // stdin/stdout/stderr to be closed. At that point, freopen() could be used // to reopen stderr/out, but it would take more massaging to fixup the file // descriptor number that freopen() uses. It's simplest to avoid all of this // complexity by just redirecting stdin to `nul' and then the C Runtime acts // as expected. unique_handle nul_read(CreateFileW(L"nul", GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, &sa, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL)); if (nul_read.get() == INVALID_HANDLE_VALUE) { fprintf(stderr, "Cannot open 'nul': %s\n", SystemErrorCodeToString(GetLastError()).c_str()); return -1; } // create pipes with non-inheritable read handle, inheritable write handle unique_handle ack_read, ack_write; if (!_create_anonymous_pipe(&ack_read, &ack_write, &sa)) { return -1; } unique_handle stdout_read, stdout_write; if (!_create_anonymous_pipe(&stdout_read, &stdout_write, &sa)) { return -1; } unique_handle stderr_read, stderr_write; if (!_create_anonymous_pipe(&stderr_read, &stderr_write, &sa)) { return -1; } /* Some programs want to launch an adb command and collect its output by * calling CreateProcess with inheritable stdout/stderr handles, then * using read() to get its output. When this happens, the stdout/stderr * handles passed to the adb client process will also be inheritable. * When starting the adb server here, care must be taken to reset them * to non-inheritable. * Otherwise, something bad happens: even if the adb command completes, * the calling process is stuck while read()-ing from the stdout/stderr * descriptors, because they're connected to corresponding handles in the * adb server process (even if the latter never uses/writes to them). * Note that even if we don't pass these handles in the STARTUPINFO struct, * if they're marked inheritable, they're still inherited, requiring us to * deal with this. * * If we're still having problems with inheriting random handles in the * future, consider using PROC_THREAD_ATTRIBUTE_HANDLE_LIST to explicitly * specify which handles should be inherited: http://blogs.msdn.com/b/oldnewthing/archive/2011/12/16/10248328.aspx */ if (!_make_handle_noninheritable(GetStdHandle(STD_INPUT_HANDLE))) { return -1; } if (!_make_handle_noninheritable(GetStdHandle(STD_OUTPUT_HANDLE))) { return -1; } if (!_make_handle_noninheritable(GetStdHandle(STD_ERROR_HANDLE))) { return -1; } STARTUPINFOW startup; ZeroMemory( &startup, sizeof(startup) ); startup.cb = sizeof(startup); startup.hStdInput = nul_read.get(); startup.hStdOutput = stdout_write.get(); startup.hStdError = stderr_write.get(); startup.dwFlags = STARTF_USESTDHANDLES; // Verify that the pipe_write handle value can be passed on the command line // as %d and that the rest of adb code can pass it around in an int. const int ack_write_as_int = cast_handle_to_int(ack_write.get()); if (cast_int_to_handle(ack_write_as_int) != ack_write.get()) { // If this fires, either handle values are larger than 32-bits or else // there is a bug in our casting. // https://msdn.microsoft.com/en-us/library/windows/desktop/aa384203%28v=vs.85%29.aspx fprintf(stderr, "Cannot fit pipe handle value into 32-bits: 0x%p\n", ack_write.get()); return -1; } // get path of current program WCHAR program_path[MAX_PATH]; const DWORD module_result = GetModuleFileNameW(NULL, program_path, arraysize(program_path)); if ((module_result >= arraysize(program_path)) || (module_result == 0)) { // String truncation or some other error. fprintf(stderr, "Cannot get executable path: %s\n", SystemErrorCodeToString(GetLastError()).c_str()); return -1; } WCHAR args[64]; snwprintf(args, arraysize(args), L"adb -P %d fork-server server --reply-fd %d", server_port, ack_write_as_int); PROCESS_INFORMATION pinfo; ZeroMemory(&pinfo, sizeof(pinfo)); if (!CreateProcessW( program_path, /* program path */ args, /* the fork-server argument will set the debug = 2 in the child */ NULL, /* process handle is not inheritable */ NULL, /* thread handle is not inheritable */ TRUE, /* yes, inherit some handles */ DETACHED_PROCESS, /* the new process doesn't have a console */ NULL, /* use parent's environment block */ NULL, /* use parent's starting directory */ &startup, /* startup info, i.e. std handles */ &pinfo )) { fprintf(stderr, "Cannot create process: %s\n", SystemErrorCodeToString(GetLastError()).c_str()); return -1; } unique_handle process_handle(pinfo.hProcess); pinfo.hProcess = NULL; // Close handles that we no longer need to complete the rest. CloseHandle(pinfo.hThread); pinfo.hThread = NULL; nul_read.reset(); ack_write.reset(); stdout_write.reset(); stderr_write.reset(); // Start threads to read from subprocess stdout/stderr and write to ours // to make subprocess errors easier to diagnose. // In the past, reading from a pipe before the child process's C Runtime // started up and called GetFileType() caused a hang: http://blogs.msdn.com/b/oldnewthing/archive/2011/12/02/10243553.aspx#10244216 // This is reportedly fixed in Windows Vista: https://support.microsoft.com/en-us/kb/2009703 // I was unable to reproduce the problem on Windows XP. It sounds like a // Windows Update may have fixed this: https://www.duckware.com/tech/peeknamedpipe.html unique_handle stdout_thread(reinterpret_cast<HANDLE>( _beginthreadex(NULL, 0, _redirect_stdout_thread, stdout_read.get(), 0, NULL))); if (stdout_thread.get() == nullptr) { fprintf(stderr, "Cannot create thread: %s\n", strerror(errno)); return -1; } stdout_read.release(); // Transfer ownership to new thread unique_handle stderr_thread(reinterpret_cast<HANDLE>( _beginthreadex(NULL, 0, _redirect_stderr_thread, stderr_read.get(), 0, NULL))); if (stderr_thread.get() == nullptr) { fprintf(stderr, "Cannot create thread: %s\n", strerror(errno)); return -1; } stderr_read.release(); // Transfer ownership to new thread bool got_ack = false; // Wait for the "OK\n" message, for the pipe to be closed, or other error. { char temp[3]; DWORD count = 0; if (ReadFile(ack_read.get(), temp, sizeof(temp), &count, NULL)) { const CHAR expected[] = "OK\n"; const DWORD expected_length = arraysize(expected) - 1; if (count == expected_length && memcmp(temp, expected, expected_length) == 0) { got_ack = true; } else { fprintf(stderr, "ADB server didn't ACK\n"); } } else { const DWORD err = GetLastError(); // If the ACK was not written and the process exited, GetLastError() // is probably ERROR_BROKEN_PIPE, in which case that info is not // useful to the user. fprintf(stderr, "could not read ok from ADB Server%s\n", err == ERROR_BROKEN_PIPE ? "" : android::base::StringPrintf(": %s", SystemErrorCodeToString(err).c_str()).c_str()); } } // Always try to wait a bit for threads reading stdout/stderr to finish. // If the process started ok, it should close the pipes causing the threads // to finish. If the process had an error, it should exit, also causing // the pipes to be closed. In that case we want to read all of the output // and write it out so that the user can diagnose failures. const DWORD thread_timeout_ms = 15 * 1000; const HANDLE threads[] = { stdout_thread.get(), stderr_thread.get() }; const DWORD wait_result = WaitForMultipleObjects(arraysize(threads), threads, TRUE, thread_timeout_ms); if (wait_result == WAIT_TIMEOUT) { // Threads did not finish after waiting a little while. Perhaps the // server didn't close pipes, or it is hung. fprintf(stderr, "Timed-out waiting for threads to finish reading from " "ADB Server\n"); // Process handles are signaled when the process exits, so if we wait // on the handle for 0 seconds and it returns 'timeout', that means that // the process is still running. if (WaitForSingleObject(process_handle.get(), 0) == WAIT_TIMEOUT) { // We could TerminateProcess(), but that seems somewhat presumptive. fprintf(stderr, "ADB Server is running: process id %lu\n", pinfo.dwProcessId); } return -1; } if (wait_result != WAIT_OBJECT_0) { fprintf(stderr, "Unexpected result waiting for threads: %lu: %s\n", wait_result, SystemErrorCodeToString(GetLastError()).c_str()); return -1; } // For now ignore the thread exit codes and assume they worked properly. if (!got_ack) { return -1; } #else /* !defined(_WIN32) */ char path[PATH_MAX]; int fd[2]; // set up a pipe so the child can tell us when it is ready. // fd[0] will be parent's end, and the child will write on fd[1] if (pipe(fd)) { fprintf(stderr, "pipe failed in launch_server, errno: %d\n", errno); return -1; } get_my_path(path, PATH_MAX); pid_t pid = fork(); if(pid < 0) return -1; if (pid == 0) { // child side of the fork adb_close(fd[0]); char str_port[30]; snprintf(str_port, sizeof(str_port), "%d", server_port); char reply_fd[30]; snprintf(reply_fd, sizeof(reply_fd), "%d", fd[1]); // child process int result = execl(path, "adb", "-P", str_port, "fork-server", "server", "--reply-fd", reply_fd, NULL); // this should not return fprintf(stderr, "OOPS! execl returned %d, errno: %d\n", result, errno); } else { // parent side of the fork char temp[3]; temp[0] = 'A'; temp[1] = 'B'; temp[2] = 'C'; // wait for the "OK\n" message adb_close(fd[1]); int ret = adb_read(fd[0], temp, 3); int saved_errno = errno; adb_close(fd[0]); if (ret < 0) { fprintf(stderr, "could not read ok from ADB Server, errno = %d\n", saved_errno); return -1; } if (ret != 3 || temp[0] != 'O' || temp[1] != 'K' || temp[2] != '\n') { fprintf(stderr, "ADB server didn't ACK\n" ); return -1; } setsid(); } #endif /* !defined(_WIN32) */ return 0; }
void Thread::start() { unsigned th_id; h_thread = reinterpret_cast<HANDLE>(_beginthreadex(nullptr, 0, thread_proc, this, 0, &th_id)); CHECK_SYS(h_thread); }
static bool windows_init_clock(struct libusb_context *ctx) { DWORD_PTR affinity, dummy; HANDLE event; LARGE_INTEGER li_frequency; int i; if (QueryPerformanceFrequency(&li_frequency)) { // The hires frequency can go as high as 4 GHz, so we'll use a conversion // to picoseconds to compute the tv_nsecs part in clock_gettime hires_frequency = li_frequency.QuadPart; hires_ticks_to_ps = UINT64_C(1000000000000) / hires_frequency; usbi_dbg("hires timer available (Frequency: %"PRIu64" Hz)", hires_frequency); // Because QueryPerformanceCounter might report different values when // running on different cores, we create a separate thread for the timer // calls, which we glue to the first available core always to prevent timing discrepancies. if (!GetProcessAffinityMask(GetCurrentProcess(), &affinity, &dummy) || (affinity == 0)) { usbi_err(ctx, "could not get process affinity: %s", windows_error_str(0)); return false; } // The process affinity mask is a bitmask where each set bit represents a core on // which this process is allowed to run, so we find the first set bit for (i = 0; !(affinity & (DWORD_PTR)(1 << i)); i++); affinity = (DWORD_PTR)(1 << i); usbi_dbg("timer thread will run on core #%d", i); event = CreateEvent(NULL, FALSE, FALSE, NULL); if (event == NULL) { usbi_err(ctx, "could not create event: %s", windows_error_str(0)); return false; } timer_thread = (HANDLE)_beginthreadex(NULL, 0, windows_clock_gettime_threaded, (void *)event, 0, (unsigned int *)&timer_thread_id); if (timer_thread == NULL) { usbi_err(ctx, "unable to create timer thread - aborting"); CloseHandle(event); return false; } if (!SetThreadAffinityMask(timer_thread, affinity)) usbi_warn(ctx, "unable to set timer thread affinity, timer discrepancies may arise"); // Wait for timer thread to init before continuing. if (WaitForSingleObject(event, INFINITE) != WAIT_OBJECT_0) { usbi_err(ctx, "failed to wait for timer thread to become ready - aborting"); CloseHandle(event); return false; } CloseHandle(event); } else { usbi_dbg("no hires timer available on this platform"); hires_frequency = 0; hires_ticks_to_ps = UINT64_C(0); } return true; }
void beacon_init (struct misc_config_s *pconfig, struct digi_config_s *pdigi) { time_t now; int j; int count; #if __WIN32__ HANDLE beacon_th; #else pthread_t beacon_tid; #endif #if DEBUG text_color_set(DW_COLOR_DEBUG); dw_printf ("beacon_init ( ... )\n"); #endif /* * Save parameters for later use. */ g_misc_config_p = pconfig; g_digi_config_p = pdigi; /* * Precompute the packet contents so any errors are * Reported once at start up time rather than for each transmission. * If a serious error is found, set type to BEACON_IGNORE and that * table entry should be ignored later on. */ for (j=0; j<g_misc_config_p->num_beacons; j++) { int chan = g_misc_config_p->beacon[j].chan; if (chan < 0) chan = 0; /* For IGate, use channel 0 call. */ if (chan < pdigi->num_chans) { if (strlen(pdigi->mycall[chan]) > 0 && strcasecmp(pdigi->mycall[chan], "NOCALL") != 0) { switch (g_misc_config_p->beacon[j].btype) { case BEACON_OBJECT: /* Object name is required. */ if (strlen(g_misc_config_p->beacon[j].objname) == 0) { text_color_set(DW_COLOR_ERROR); dw_printf ("Config file, line %d: OBJNAME is required for OBEACON.\n", g_misc_config_p->beacon[j].lineno); g_misc_config_p->beacon[j].btype = BEACON_IGNORE; continue; } /* Fall thru. Ignore any warning about missing break. */ case BEACON_POSITION: /* Location is required. */ if (g_misc_config_p->beacon[j].lat == G_UNKNOWN || g_misc_config_p->beacon[j].lon == G_UNKNOWN) { text_color_set(DW_COLOR_ERROR); dw_printf ("Config file, line %d: Latitude and longitude are required.\n", g_misc_config_p->beacon[j].lineno); g_misc_config_p->beacon[j].btype = BEACON_IGNORE; continue; } break; case BEACON_TRACKER: #if defined(GPS_ENABLED) || defined(DEBUG_SIM) g_using_gps++; #else text_color_set(DW_COLOR_ERROR); dw_printf ("Config file, line %d: GPS tracker feature is not enabled.\n", g_misc_config_p->beacon[j].lineno); g_misc_config_p->beacon[j].btype = BEACON_IGNORE; continue; #endif break; case BEACON_CUSTOM: /* INFO is required. */ if (g_misc_config_p->beacon[j].custom_info == NULL) { text_color_set(DW_COLOR_ERROR); dw_printf ("Config file, line %d: INFO is required for custom beacon.\n", g_misc_config_p->beacon[j].lineno); g_misc_config_p->beacon[j].btype = BEACON_IGNORE; continue; } break; case BEACON_IGNORE: break; } } else { text_color_set(DW_COLOR_ERROR); dw_printf ("Config file, line %d: MYCALL must be set for beacon on channel %d. \n", g_misc_config_p->beacon[j].lineno, chan); g_misc_config_p->beacon[j].btype = BEACON_IGNORE; } } else { text_color_set(DW_COLOR_ERROR); dw_printf ("Config file, line %d: Invalid channel number %d for beacon. \n", g_misc_config_p->beacon[j].lineno, chan); g_misc_config_p->beacon[j].btype = BEACON_IGNORE; } } /* * Calculate next time for each beacon. */ now = time(NULL); for (j=0; j<g_misc_config_p->num_beacons; j++) { #if DEBUG text_color_set(DW_COLOR_DEBUG); dw_printf ("beacon[%d] chan=%d, delay=%d, every=%d\n", j, g_misc_config_p->beacon[j].chan, g_misc_config_p->beacon[j].delay, g_misc_config_p->beacon[j].every); #endif g_misc_config_p->beacon[j].next = now + g_misc_config_p->beacon[j].delay; } /* * Connect to GPS receiver if any tracker beacons are configured. * If open fails, disable all tracker beacons. */ #if DEBUG_SIM g_using_gps = 1; #elif ENABLE_GPS if (g_using_gps > 0) { int err; err = dwgps_init(); if (err != 0) { text_color_set(DW_COLOR_ERROR); dw_printf ("All tracker beacons disabled.\n"); g_using_gps = 0; for (j=0; j<g_misc_config_p->num_beacons; j++) { if (g_misc_config_p->beacon[j].btype == BEACON_TRACKER) { g_misc_config_p->beacon[j].btype = BEACON_IGNORE; } } } } #endif /* * Start up thread for processing only if at least one is valid. */ count = 0; for (j=0; j<g_misc_config_p->num_beacons; j++) { if (g_misc_config_p->beacon[j].btype != BEACON_IGNORE) { count++; } } if (count >= 1) { #if __WIN32__ beacon_th = (HANDLE)_beginthreadex (NULL, 0, &beacon_thread, NULL, 0, NULL); if (beacon_th == NULL) { text_color_set(DW_COLOR_ERROR); dw_printf ("Could not create beacon thread\n"); return; } #else int e; e = pthread_create (&beacon_tid, NULL, beacon_thread, (void *)0); if (e != 0) { text_color_set(DW_COLOR_ERROR); perror("Could not create beacon thread"); return; } #endif } } /* end beacon_init */
DWORD WINAPI CEgTcpDriver::Start(IEgTcpDriverEvents * pEvents, const COINIT ThreadingModel, const unsigned short usServerPort) { if (pEvents == NULL) return ERROR_INVALID_PARAMETER; CAutoLock lock(&m_InitLock); if (m_bInited) return ERROR_ALREADY_INITIALIZED; m_ThreadingModel = ThreadingModel; m_pEvents = pEvents; m_usServerPort = usServerPort; for(int i = 0; i < WSATOTAL_EVENTS; i++) { m_hWsaEvents[i] = WSACreateEvent(); if (WSA_INVALID_EVENT == m_hWsaEvents[i]) return WSAGetLastError(); } m_hIocp = CreateIoCompletionPort(INVALID_HANDLE_VALUE, NULL, 0, 0); if (NULL == m_hIocp) return GetLastError(); SYSTEM_INFO systemInfo; GetSystemInfo(&systemInfo); m_dwThreadCount = 1/*systemInfo.dwNumberOfProcessors * 2*/; // Create worker threads to service the overlapped I/O requests. The decision // to create 1 worker threads per CPU in the system is a heuristic. Also, // note that thread handles are closed right away, because we will not need them // and the worker threads will continue to execute. unsigned long hThread; UINT dwThreadId; for (DWORD dwCPU=0; dwCPU < m_dwThreadCount; dwCPU++) { hThread = _beginthreadex(NULL, 0, WorkerThread, this, 0, &dwThreadId); if (hThread == -1) return GetLastError(); m_hThreads.push_back((HANDLE)hThread); } hThread = _beginthreadex(NULL, 0, WsaEventThread, this, 0, &dwThreadId); if (hThread == -1) return GetLastError(); m_hWSAEventThread = (HANDLE)hThread; if (m_usServerPort != CLIENT_ONLY) { DWORD dwErr = CreateListenSocket(); if (dwErr != 0) return dwErr; dwErr = CreateAcceptSocket(TRUE); if (dwErr != 0) return dwErr; } m_bInited = TRUE; return 0; }
void launchKssServiceThread(){ setContinueKssThread(TRUE); setKssServiceThread( (ThreadHandler) _beginthreadex( NULL, 0, &doKssService, NULL, 0, NULL ) ); }
Eina_Bool ecore_con_local_connect(Ecore_Con_Server *svr, Eina_Bool (*cb_done)(void *data, Ecore_Fd_Handler *fd_handler)) { char buf[256]; Ecore_Win32_Handler *handler_read; Ecore_Win32_Handler *handler_peek; if ((svr->type & ECORE_CON_TYPE) == ECORE_CON_LOCAL_ABSTRACT) { ERR("Your system does not support abstract sockets!"); return EINA_FALSE; } if ((svr->type & ECORE_CON_TYPE) == ECORE_CON_LOCAL_USER) snprintf(buf, sizeof(buf), "\\\\.\\pipe\\%s", svr->name); else if ((svr->type & ECORE_CON_TYPE) == ECORE_CON_LOCAL_SYSTEM) { const char *computername; computername = getenv("COMPUTERNAME"); snprintf(buf, sizeof(buf), "\\\\%s\\pipe\\%s", computername, svr->name); } while (1) { svr->pipe = CreateFile(buf, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL); if (svr->pipe != INVALID_HANDLE_VALUE) break; /* if pipe not busy, we exit */ if (GetLastError() != ERROR_PIPE_BUSY) { ERR("Connection to a server failed"); return EINA_FALSE; } /* pipe busy, so we wait for it */ if (!WaitNamedPipe(buf, NMPWAIT_WAIT_FOREVER)) { ERR("Can not wait for a server"); goto close_pipe; } } svr->path = strdup(buf); if (!svr->path) { ERR("Allocation failed"); goto close_pipe; } svr->event_read = CreateEvent(NULL, TRUE, FALSE, NULL); if (!svr->event_read) { ERR("Can not create event read"); goto free_path; } handler_read = ecore_main_win32_handler_add(svr->event_read, _ecore_con_local_win32_client_read_server_handler, svr); if (!handler_read) { ERR("Can not create handler read"); goto close_event_read; } svr->event_peek = CreateEvent(NULL, TRUE, FALSE, NULL); if (!svr->event_peek) { ERR("Can not create event peek"); goto del_handler_read; } handler_peek = ecore_main_win32_handler_add(svr->event_peek, _ecore_con_local_win32_client_peek_server_handler, svr); if (!handler_peek) { ERR("Can not create handler peek"); goto close_event_peek; } svr->thread_read = (HANDLE)_beginthreadex(NULL, 0, _ecore_con_local_win32_client_read_server_thread, svr, CREATE_SUSPENDED, NULL); if (!svr->thread_read) { ERR("Can not launch thread"); goto del_handler_peek; } if (!svr->delete_me) ecore_con_event_server_add(svr); ResumeThread(svr->thread_read); return EINA_TRUE; del_handler_peek: ecore_main_win32_handler_del(handler_peek); close_event_peek: CloseHandle(svr->event_peek); del_handler_read: ecore_main_win32_handler_del(handler_read); close_event_read: CloseHandle(svr->event_read); free_path: free(svr->path); svr->path = NULL; close_pipe: CloseHandle(svr->pipe); return EINA_FALSE; }
void child_main(apr_pool_t *pconf) { apr_status_t status; apr_hash_t *ht; ap_listen_rec *lr; HANDLE child_events[2]; HANDLE *child_handles; int listener_started = 0; int threads_created = 0; int watch_thread; int time_remains; int cld; unsigned tid; int rv; int i; apr_pool_create(&pchild, pconf); apr_pool_tag(pchild, "pchild"); ap_run_child_init(pchild, ap_server_conf); ht = apr_hash_make(pchild); /* Initialize the child_events */ max_requests_per_child_event = CreateEvent(NULL, TRUE, FALSE, NULL); if (!max_requests_per_child_event) { ap_log_error(APLOG_MARK, APLOG_CRIT, apr_get_os_error(), ap_server_conf, "Child %lu: Failed to create a max_requests event.", my_pid); exit(APEXIT_CHILDINIT); } child_events[0] = exit_event; child_events[1] = max_requests_per_child_event; allowed_globals.jobsemaphore = CreateSemaphore(NULL, 0, 1000000, NULL); apr_thread_mutex_create(&allowed_globals.jobmutex, APR_THREAD_MUTEX_DEFAULT, pchild); /* * Wait until we have permission to start accepting connections. * start_mutex is used to ensure that only one child ever * goes into the listen/accept loop at once. */ status = apr_proc_mutex_lock(start_mutex); if (status != APR_SUCCESS) { ap_log_error(APLOG_MARK,APLOG_ERR, status, ap_server_conf, "Child %lu: Failed to acquire the start_mutex. Process will exit.", my_pid); exit(APEXIT_CHILDINIT); } ap_log_error(APLOG_MARK,APLOG_NOTICE, APR_SUCCESS, ap_server_conf, "Child %lu: Acquired the start mutex.", my_pid); /* * Create the worker thread dispatch IOCompletionPort * on Windows NT/2000 */ if (use_acceptex) { /* Create the worker thread dispatch IOCP */ ThreadDispatchIOCP = CreateIoCompletionPort(INVALID_HANDLE_VALUE, NULL, 0, 0); /* CONCURRENT ACTIVE THREADS */ apr_thread_mutex_create(&qlock, APR_THREAD_MUTEX_DEFAULT, pchild); qwait_event = CreateEvent(NULL, TRUE, FALSE, NULL); if (!qwait_event) { ap_log_error(APLOG_MARK, APLOG_CRIT, apr_get_os_error(), ap_server_conf, "Child %lu: Failed to create a qwait event.", my_pid); exit(APEXIT_CHILDINIT); } } /* * Create the pool of worker threads */ ap_log_error(APLOG_MARK,APLOG_NOTICE, APR_SUCCESS, ap_server_conf, "Child %lu: Starting %d worker threads.", my_pid, ap_threads_per_child); child_handles = (HANDLE) apr_pcalloc(pchild, ap_threads_per_child * sizeof(HANDLE)); apr_thread_mutex_create(&child_lock, APR_THREAD_MUTEX_DEFAULT, pchild); while (1) { for (i = 0; i < ap_threads_per_child; i++) { int *score_idx; int status = ap_scoreboard_image->servers[0][i].status; if (status != SERVER_GRACEFUL && status != SERVER_DEAD) { continue; } ap_update_child_status_from_indexes(0, i, SERVER_STARTING, NULL); child_handles[i] = (HANDLE) _beginthreadex(NULL, (unsigned)ap_thread_stacksize, worker_main, (void *) i, 0, &tid); if (child_handles[i] == 0) { ap_log_error(APLOG_MARK, APLOG_CRIT, apr_get_os_error(), ap_server_conf, "Child %lu: _beginthreadex failed. Unable to create all worker threads. " "Created %d of the %d threads requested with the ThreadsPerChild configuration directive.", my_pid, threads_created, ap_threads_per_child); ap_signal_parent(SIGNAL_PARENT_SHUTDOWN); goto shutdown; } threads_created++; /* Save the score board index in ht keyed to the thread handle. We need this * when cleaning up threads down below... */ apr_thread_mutex_lock(child_lock); score_idx = apr_pcalloc(pchild, sizeof(int)); *score_idx = i; apr_hash_set(ht, &child_handles[i], sizeof(HANDLE), score_idx); apr_thread_mutex_unlock(child_lock); } /* Start the listener only when workers are available */ if (!listener_started && threads_created) { create_listener_thread(); listener_started = 1; winnt_mpm_state = AP_MPMQ_RUNNING; } if (threads_created == ap_threads_per_child) { break; } /* Check to see if the child has been told to exit */ if (WaitForSingleObject(exit_event, 0) != WAIT_TIMEOUT) { break; } /* wait for previous generation to clean up an entry in the scoreboard */ apr_sleep(1 * APR_USEC_PER_SEC); } /* Wait for one of three events: * exit_event: * The exit_event is signaled by the parent process to notify * the child that it is time to exit. * * max_requests_per_child_event: * This event is signaled by the worker threads to indicate that * the process has handled MaxRequestsPerChild connections. * * TIMEOUT: * To do periodic maintenance on the server (check for thread exits, * number of completion contexts, etc.) * * XXX: thread exits *aren't* being checked. * * XXX: other_child - we need the process handles to the other children * in order to map them to apr_proc_other_child_read (which is not * named well, it's more like a_p_o_c_died.) * * XXX: however - if we get a_p_o_c handle inheritance working, and * the parent process creates other children and passes the pipes * to our worker processes, then we have no business doing such * things in the child_main loop, but should happen in master_main. */ while (1) { #if !APR_HAS_OTHER_CHILD rv = WaitForMultipleObjects(2, (HANDLE *) child_events, FALSE, INFINITE); cld = rv - WAIT_OBJECT_0; #else rv = WaitForMultipleObjects(2, (HANDLE *) child_events, FALSE, 1000); cld = rv - WAIT_OBJECT_0; if (rv == WAIT_TIMEOUT) { apr_proc_other_child_refresh_all(APR_OC_REASON_RUNNING); } else #endif if (rv == WAIT_FAILED) { /* Something serious is wrong */ ap_log_error(APLOG_MARK, APLOG_CRIT, apr_get_os_error(), ap_server_conf, "Child %lu: WAIT_FAILED -- shutting down server", my_pid); break; } else if (cld == 0) { /* Exit event was signaled */ ap_log_error(APLOG_MARK, APLOG_NOTICE, APR_SUCCESS, ap_server_conf, "Child %lu: Exit event signaled. Child process is ending.", my_pid); break; } else { /* MaxRequestsPerChild event set by the worker threads. * Signal the parent to restart */ ap_log_error(APLOG_MARK, APLOG_NOTICE, APR_SUCCESS, ap_server_conf, "Child %lu: Process exiting because it reached " "MaxRequestsPerChild. Signaling the parent to " "restart a new child process.", my_pid); ap_signal_parent(SIGNAL_PARENT_RESTART); break; } } /* * Time to shutdown the child process */ shutdown: winnt_mpm_state = AP_MPMQ_STOPPING; /* Setting is_graceful will cause threads handling keep-alive connections * to close the connection after handling the current request. */ is_graceful = 1; /* Close the listening sockets. Note, we must close the listeners * before closing any accept sockets pending in AcceptEx to prevent * memory leaks in the kernel. */ for (lr = ap_listeners; lr ; lr = lr->next) { apr_socket_close(lr->sd); } /* Shutdown listener threads and pending AcceptEx socksts * but allow the worker threads to continue consuming from * the queue of accepted connections. */ shutdown_in_progress = 1; Sleep(1000); /* Tell the worker threads to exit */ workers_may_exit = 1; /* Release the start_mutex to let the new process (in the restart * scenario) a chance to begin accepting and servicing requests */ rv = apr_proc_mutex_unlock(start_mutex); if (rv == APR_SUCCESS) { ap_log_error(APLOG_MARK,APLOG_NOTICE, rv, ap_server_conf, "Child %lu: Released the start mutex", my_pid); } else { ap_log_error(APLOG_MARK,APLOG_ERR, rv, ap_server_conf, "Child %lu: Failure releasing the start mutex", my_pid); } /* Shutdown the worker threads */ if (!use_acceptex) { for (i = 0; i < threads_created; i++) { add_job(INVALID_SOCKET); } } else { /* Windows NT/2000 */ /* Post worker threads blocked on the ThreadDispatch IOCompletion port */ while (g_blocked_threads > 0) { ap_log_error(APLOG_MARK,APLOG_INFO, APR_SUCCESS, ap_server_conf, "Child %lu: %d threads blocked on the completion port", my_pid, g_blocked_threads); for (i=g_blocked_threads; i > 0; i--) { PostQueuedCompletionStatus(ThreadDispatchIOCP, 0, IOCP_SHUTDOWN, NULL); } Sleep(1000); } /* Empty the accept queue of completion contexts */ apr_thread_mutex_lock(qlock); while (qhead) { CloseHandle(qhead->Overlapped.hEvent); closesocket(qhead->accept_socket); qhead = qhead->next; } apr_thread_mutex_unlock(qlock); } /* Give busy threads a chance to service their connections, * (no more than the global server timeout period which * we track in msec remaining). */ watch_thread = 0; time_remains = (int)(ap_server_conf->timeout / APR_TIME_C(1000)); while (threads_created) { int nFailsafe = MAXIMUM_WAIT_OBJECTS; DWORD dwRet; /* Every time we roll over to wait on the first group * of MAXIMUM_WAIT_OBJECTS threads, take a breather, * and infrequently update the error log. */ if (watch_thread >= threads_created) { if ((time_remains -= 100) < 0) break; /* Every 30 seconds give an update */ if ((time_remains % 30000) == 0) { ap_log_error(APLOG_MARK, APLOG_NOTICE, APR_SUCCESS, ap_server_conf, "Child %lu: Waiting %d more seconds " "for %d worker threads to finish.", my_pid, time_remains / 1000, threads_created); } /* We'll poll from the top, 10 times per second */ Sleep(100); watch_thread = 0; } /* Fairness, on each iteration we will pick up with the thread * after the one we just removed, even if it's a single thread. * We don't block here. */ dwRet = WaitForMultipleObjects(min(threads_created - watch_thread, MAXIMUM_WAIT_OBJECTS), child_handles + watch_thread, 0, 0); if (dwRet == WAIT_FAILED) { break; } if (dwRet == WAIT_TIMEOUT) { /* none ready */ watch_thread += MAXIMUM_WAIT_OBJECTS; continue; } else if (dwRet >= WAIT_ABANDONED_0) { /* We just got the ownership of the object, which * should happen at most MAXIMUM_WAIT_OBJECTS times. * It does NOT mean that the object is signaled. */ if ((nFailsafe--) < 1) break; } else { watch_thread += (dwRet - WAIT_OBJECT_0); if (watch_thread >= threads_created) break; cleanup_thread(child_handles, &threads_created, watch_thread); } } /* Kill remaining threads off the hard way */ if (threads_created) { ap_log_error(APLOG_MARK,APLOG_NOTICE, APR_SUCCESS, ap_server_conf, "Child %lu: Terminating %d threads that failed to exit.", my_pid, threads_created); } for (i = 0; i < threads_created; i++) { int *score_idx; TerminateThread(child_handles[i], 1); CloseHandle(child_handles[i]); /* Reset the scoreboard entry for the thread we just whacked */ score_idx = apr_hash_get(ht, &child_handles[i], sizeof(HANDLE)); if (score_idx) { ap_update_child_status_from_indexes(0, *score_idx, SERVER_DEAD, NULL); } } ap_log_error(APLOG_MARK,APLOG_NOTICE, APR_SUCCESS, ap_server_conf, "Child %lu: All worker threads have exited.", my_pid); CloseHandle(allowed_globals.jobsemaphore); apr_thread_mutex_destroy(allowed_globals.jobmutex); apr_thread_mutex_destroy(child_lock); if (use_acceptex) { apr_thread_mutex_destroy(qlock); CloseHandle(qwait_event); } apr_pool_destroy(pchild); CloseHandle(exit_event); }
static void create_stdin_waiter_thread(void) { netsnmp_assert(s_thread_handle == 0); s_thread_handle = (HANDLE)_beginthreadex(0, 0, wait_for_stdin, 0, 0, &s_threadid); netsnmp_assert(s_thread_handle != 0); }
static os_status_t OS_THREAD_CALLING_CONVENTION _thread_create(os_thread_function_t func, void *data, os_size_t stack_size, uint8_t detached, os_thread_t **newthread) { os_thread_t *thread = NULL; os_status_t status = OS_FAIL; if (*newthread) { *newthread = NULL; } if (!func || !(thread = (os_thread_t *)os_calloc(1, sizeof(os_thread_t)))) { goto done; } thread->private_data = data; thread->function = func; thread->stack_size = stack_size; thread->detached = detached; #if defined(WIN32) thread->handle = (void *)_beginthreadex(NULL, (unsigned)thread->stack_size, (unsigned int (__stdcall *)(void *))thread_launch, thread, 0, NULL); if (!thread->handle) { goto fail; } if (detached) { CloseHandle(thread->handle); } status = OS_SUCCESS; goto done; #else if (pthread_attr_init(&thread->attribute) != 0) { goto fail; } if (detached) { if (pthread_attr_setdetachstate(&thread->attribute, PTHREAD_CREATE_DETACHED) != 0) { goto failpthread; } } if (thread->stack_size && pthread_attr_setstacksize(&thread->attribute, thread->stack_size) != 0) { goto failpthread; } if (pthread_create(&thread->handle, &thread->attribute, thread_launch, thread) != 0) { goto failpthread; } if (newthread) { *newthread = thread; } status = OS_SUCCESS; goto done; failpthread: pthread_attr_destroy(&thread->attribute); #endif fail: if (thread) { os_safe_free(thread); } done: return status; }
void CNavDesktopModule::_UpdateSelf() { //升级 _beginthreadex(NULL, 0, UpdateSelfProc, this, 0, NULL); }
/** * Initialise WinPcap and return our MAC address. */ int pkt_eth_init (mac_address *mac_addr) { struct { PACKET_OID_DATA oidData; char descr[512]; } oid; const ADAPTER *adapter = NULL; DWORD thread_id; BOOL is_up; if (_watt_is_win9x) /**< \todo Support Win-9x too */ { (*_printf) (_LANG("Win-NT or later reqired.\n")); _pkt_errno = PDERR_GEN_FAIL; return (WERR_ILL_DOSX); } if (!_watt_no_config || _watt_user_config_fn) parse_config_pass_1(); _pkt_inf = calloc (sizeof(*_pkt_inf), 1); if (!_pkt_inf) { (*_printf) (_LANG("Failed to allocate WinPcap DRIVER data.\n")); _pkt_errno = PDERR_GEN_FAIL; return (WERR_NO_MEM); } if (debug_on >= 2 && dump_fname[0]) dump_file = fopen_excl (ExpandVarStr(dump_fname), "w+t"); if (!PacketInitModule(TRUE, dump_file)) { (*_printf) (_LANG("Failed to initialise WinPcap.\n")); pkt_release(); _pkt_errno = PDERR_NO_DRIVER; return (WERR_PKT_ERROR); } if (!_pktdrvrname[0] && !find_adapter(_pktdrvrname,sizeof(_pktdrvrname))) { (*_printf) (_LANG("No WinPcap driver found.\n")); _pkt_errno = PDERR_NO_DRIVER; return (WERR_NO_DRIVER); } TCP_CONSOLE_MSG (2, ("device %s\n", _pktdrvrname)); adapter = PacketOpenAdapter (_pktdrvrname); if (!adapter) { if (debug_on > 0) (*_printf) (_LANG("PacketOpenAdapter (\"%s\") failed; %s\n"), _pktdrvrname, win_strerror(GetLastError())); pkt_release(); return (WERR_NO_DRIVER); } _pkt_inf->adapter = adapter; #if defined(USE_DYN_PACKET) _pkt_inf->adapter_info = NULL; #else _pkt_inf->adapter_info = PacketFindAdInfo (_pktdrvrname); #endif /* Query the NIC driver for the adapter description */ memset (&oid, 0, sizeof(oid)); oid.oidData.Oid = OID_GEN_VENDOR_DESCRIPTION; oid.oidData.Length = sizeof(oid.descr); if (PacketRequest (adapter, FALSE, &oid.oidData)) StrLcpy (_pktdrvr_descr, (char*)oid.oidData.Data, sizeof(_pktdrvr_descr)); else { (*_printf) (_LANG("PacketRequest() failed; %s\n"), win_strerror(GetLastError())); pkt_release(); return (WERR_PKT_ERROR); } if (!get_interface_type(&_pktdevclass)) { pkt_release(); return (WERR_PKT_ERROR); } if (get_connected_status(&is_up) && !is_up) (*_printf) (_LANG("Warning: the adapter %s is down\n"), _pktdrvrname); switch (_pktdevclass) { case PDCLASS_TOKEN: _pkt_ip_ofs = sizeof(tok_Header); break; case PDCLASS_ETHER: _pkt_ip_ofs = sizeof(eth_Header); break; case PDCLASS_FDDI: _pkt_ip_ofs = sizeof(fddi_Header); break; case PDCLASS_ARCNET: _pkt_ip_ofs = ARC_HDRLEN; break; default: pkt_release(); (*_printf) (_LANG("WinPcap-ERROR: Unsupported driver class %dh\n"), _pktdevclass); _pkt_errno = PDERR_NO_CLASS; return (WERR_PKT_ERROR); } if (!pkt_get_addr(mac_addr)) /* get our MAC address */ { pkt_release(); return (WERR_PKT_ERROR); } pktq_init (&_pkt_inf->pkt_queue, sizeof(_pkt_inf->rx_buf[0]), /* RX_SIZE */ DIM(_pkt_inf->rx_buf), /* RX_BUFS */ (char*)&_pkt_inf->rx_buf); _pkt_inf->npf_buf_size = RX_SIZE * pkt_num_rx_bufs; _pkt_inf->npf_buf = malloc (_pkt_inf->npf_buf_size); if (!_pkt_inf->npf_buf) { (*_printf) (_LANG("Failed to allocate %d byte Rx buffer.\n"), _pkt_inf->npf_buf_size); pkt_release(); _pkt_errno = PDERR_GEN_FAIL; return (WERR_NO_MEM); } PacketSetMode (adapter, PACKET_MODE_CAPT); PacketSetBuff (adapter, _pkt_inf->npf_buf_size); PacketSetMinToCopy (adapter, ETH_MIN); /* PacketReceivePacket() blocks until something is received */ PacketSetReadTimeout ((ADAPTER*)adapter, 0); /* Set Rx-mode forced via config. */ if (_pkt_forced_rxmode != -1) { _pkt_forced_rxmode &= 0xFFFF; /* clear bits not set via ARG_ATOX_W */ if (_pkt_forced_rxmode == 0 || /* check illegal bit-values */ (_pkt_forced_rxmode & 0x10) || (_pkt_forced_rxmode & 0x40) || (_pkt_forced_rxmode > 0x80)) { TCP_CONSOLE_MSG (0, ("Illegal Rx-mode (0x%02X) specified\n", _pkt_forced_rxmode)); _pkt_forced_rxmode = -1; } } if (pkt_get_rcv_mode()) _pkt_rxmode0 = _pkt_rxmode; if (_pkt_forced_rxmode != -1) pkt_set_rcv_mode (_pkt_forced_rxmode); else pkt_set_rcv_mode (RXMODE_DEFAULT); #if 1 _pkt_inf->recv_thread = CreateThread (NULL, 2048, pkt_recv_thread, NULL, 0, &thread_id); #else _pkt_inf->recv_thread = _beginthreadex (NULL, 2048, pkt_recv_thread, NULL, 0, &thread_id); #endif if (!_pkt_inf->recv_thread) { (*_printf) (_LANG("Failed to create receiver thread; %s\n"), win_strerror(GetLastError())); pkt_release(); _pkt_errno = PDERR_GEN_FAIL; return (WERR_PKT_ERROR); } if (thr_realtime) SetThreadPriority (_pkt_inf->recv_thread, THREAD_PRIORITY_TIME_CRITICAL); TCP_CONSOLE_MSG (2, ("capture thread-id %lu\n", thread_id)); #if defined(USE_DEBUG) if (debug_on >= 2) { (*_printf) ("link-details:\n"); show_link_details(); } #endif return (0); }
int main (int argc, char *argv []) { #if defined XS_HAVE_WINDOWS HANDLE local_thread; #else pthread_t local_thread; #endif void *ctx; void *s; int rc; int i; xs_msg_t msg; void *watch; unsigned long elapsed; unsigned long throughput; double megabits; if (argc != 3) { printf ("usage: thread_thr <message-size> <message-count>\n"); return 1; } message_size = atoi (argv [1]); message_count = atoi (argv [2]); ctx = xs_init (); if (!ctx) { printf ("error in xs_init: %s\n", xs_strerror (errno)); return -1; } s = xs_socket (ctx, XS_PULL); if (!s) { printf ("error in xs_socket: %s\n", xs_strerror (errno)); return -1; } rc = xs_bind (s, "inproc://thr_test"); if (rc == -1) { printf ("error in xs_bind: %s\n", xs_strerror (errno)); return -1; } #if defined XS_HAVE_WINDOWS local_thread = (HANDLE) _beginthreadex (NULL, 0, worker, ctx, 0 , NULL); if (local_thread == 0) { printf ("error in _beginthreadex\n"); return -1; } #else rc = pthread_create (&local_thread, NULL, worker, ctx); if (rc != 0) { printf ("error in pthread_create: %s\n", xs_strerror (rc)); return -1; } #endif rc = xs_msg_init (&msg); if (rc != 0) { printf ("error in xs_msg_init: %s\n", xs_strerror (errno)); return -1; } printf ("message size: %d [B]\n", (int) message_size); printf ("message count: %d\n", (int) message_count); rc = xs_recvmsg (s, &msg, 0); if (rc < 0) { printf ("error in xs_recvmsg: %s\n", xs_strerror (errno)); return -1; } if (xs_msg_size (&msg) != message_size) { printf ("message of incorrect size received\n"); return -1; } watch = xs_stopwatch_start (); for (i = 0; i != message_count - 1; i++) { rc = xs_recvmsg (s, &msg, 0); if (rc < 0) { printf ("error in xs_recvmsg: %s\n", xs_strerror (errno)); return -1; } if (xs_msg_size (&msg) != message_size) { printf ("message of incorrect size received\n"); return -1; } } elapsed = xs_stopwatch_stop (watch); if (elapsed == 0) elapsed = 1; rc = xs_msg_close (&msg); if (rc != 0) { printf ("error in xs_msg_close: %s\n", xs_strerror (errno)); return -1; } #if defined XS_HAVE_WINDOWS DWORD rc2 = WaitForSingleObject (local_thread, INFINITE); if (rc2 == WAIT_FAILED) { printf ("error in WaitForSingleObject\n"); return -1; } BOOL rc3 = CloseHandle (local_thread); if (rc3 == 0) { printf ("error in CloseHandle\n"); return -1; } #else rc = pthread_join (local_thread, NULL); if (rc != 0) { printf ("error in pthread_join: %s\n", xs_strerror (rc)); return -1; } #endif rc = xs_close (s); if (rc != 0) { printf ("error in xs_close: %s\n", xs_strerror (errno)); return -1; } rc = xs_term (ctx); if (rc != 0) { printf ("error in xs_term: %s\n", xs_strerror (errno)); return -1; } throughput = (unsigned long) ((double) message_count / (double) elapsed * 1000000); megabits = (double) (throughput * message_size * 8) / 1000000; printf ("mean throughput: %d [msg/s]\n", (int) throughput); printf ("mean throughput: %.3f [Mb/s]\n", (double) megabits); return 0; }
/* * The ServiceMain function to start service. */ VOID WINAPI ServiceMain (DWORD argc, LPTSTR argv[]) { SECURITY_ATTRIBUTES SecurityAttributes; DWORD dwThreadId; /* * Input Arguments to function startup */ DWORD ArgCount = 0; LPTSTR *ArgArray = NULL; TCHAR szRegKey[512]; TCHAR szValue[128]; DWORD nSize; HKEY hParamKey = NULL; /* To read startup parameters */ DWORD TotalParams = 0; DWORD i; InputParams ThreadInputParams; /* * Build the Input parameters to pass to worker thread */ /* * SCM sends Service Name as first arg, increment to point * arguments user specified while starting contorl agent */ /* * Read registry parameter */ ArgCount = 1; /* * Create Registry Key path */ _snprintf (szRegKey, sizeof(szRegKey), "%s%s\\%s", _T ("SYSTEM\\CurrentControlSet\\Services\\"), app_name, "Parameters"); if (RegOpenKeyEx (HKEY_LOCAL_MACHINE, szRegKey, 0, KEY_ALL_ACCESS, &hParamKey) == ERROR_SUCCESS) { /* * Read startup Configuration information */ /* * Find number of subkeys inside parameters */ if (RegQueryInfoKey (hParamKey, NULL, NULL, 0, NULL, NULL, NULL, &TotalParams, NULL, NULL, NULL, NULL) == ERROR_SUCCESS) { if (TotalParams != 0) { ArgCount += TotalParams; /* * Allocate memory to hold strings */ ArgArray = (LPTSTR *) malloc (sizeof (LPTSTR) * ArgCount); /* * Copy first argument */ ArgArray[0] = _tcsdup (argv[0]); for (i = 1; i <= TotalParams; i++) { /* * Create Subkey value name */ _snprintf (szRegKey, sizeof(szRegKey), "%s%d", "Param", i); /* * Set size */ nSize = 128; RegQueryValueEx (hParamKey, szRegKey, 0, NULL, (LPBYTE) & szValue, &nSize); ArgArray[i] = _tcsdup (szValue); } } } RegCloseKey (hParamKey); } if (ArgCount == 1) { /* * No statup agrs are given */ ThreadInputParams.Argc = argc; ThreadInputParams.Argv = argv; } else { ThreadInputParams.Argc = ArgCount; ThreadInputParams.Argv = ArgArray; } /* * Register Service Control Handler */ hServiceStatus = RegisterServiceCtrlHandler (app_name, ControlHandler); if (hServiceStatus == 0) { WriteToEventLog (EVENTLOG_ERROR_TYPE, _T ("RegisterServiceCtrlHandler failed")); return; } /* * Update the service status to START_PENDING */ UpdateServiceStatus (SERVICE_START_PENDING, NO_ERROR, SCM_WAIT_INTERVAL); /* * Spin of worker thread, which does majority of the work */ TRY { if (SetSimpleSecurityAttributes (&SecurityAttributes) == FALSE) { WriteToEventLog (EVENTLOG_ERROR_TYPE, _T ("Couldn't init security attributes")); LEAVE; } hServiceThread = (void *) _beginthreadex (&SecurityAttributes, 0, ThreadFunction, (void *) &ThreadInputParams, 0, &dwThreadId); if (hServiceThread == NULL) { WriteToEventLog (EVENTLOG_ERROR_TYPE, _T ("Couldn't start worker thread")); LEAVE; } /* * Set Service Status to Running */ UpdateServiceStatus (SERVICE_RUNNING, NO_ERROR, SCM_WAIT_INTERVAL); /* * Wait for termination event and worker thread to * * spin down. */ WaitForSingleObject (hServiceThread, INFINITE); } FINALLY { /* * Release resources */ UpdateServiceStatus (SERVICE_STOPPED, NO_ERROR, SCM_WAIT_INTERVAL); if (hServiceThread) CloseHandle (hServiceThread); FreeSecurityAttributes (&SecurityAttributes); /* * Delete allocated argument list */ if (ArgCount > 1 && ArgArray != NULL) { /* * Delete all strings */ for (i = 0; i < ArgCount; i++) { free (ArgArray[i]); } free (ArgArray); } } }
COwnThread::COwnThread(void) { //proc.proccess = &COwnThread::process; handle = (HANDLE)_beginthreadex(NULL,0,stdcall,this,0,NULL); }
//////////////////////////////////////////////////////////////////////////////// // // FUNCTION: CIOCPServer::InitializeIOCP // // DESCRIPTION: Create a dummy socket and associate a completion port with it. // once completion port is create we can dicard the socket // // INPUTS: // // NOTES: // // MODIFICATIONS: // // Name Date Version Comments // N T ALMOND 06042001 1.0 Origin // //////////////////////////////////////////////////////////////////////////////// bool CIOCPServer::InitializeIOCP(void) { SOCKET s; DWORD i; UINT nThreadID; SYSTEM_INFO systemInfo; // // First open a temporary socket that we will use to create the // completion port. In NT 3.51 it will not be necessary to specify // the FileHandle parameter of CreateIoCompletionPort()--it will // be legal to specify FileHandle as NULL. However, for NT 3.5 // we need an overlapped file handle. // s = socket(AF_INET, SOCK_STREAM, IPPROTO_IP); if (s == INVALID_SOCKET) return false; // Create the completion port that will be used by all the worker // threads. m_hCompletionPort = CreateIoCompletionPort((HANDLE)s, NULL, 0, 0); if (m_hCompletionPort == NULL) { closesocket(s); return false; } // Close the socket, we don't need it any longer. closesocket(s); // 创建完成端口后就关闭? // Determine how many processors are on the system. GetSystemInfo(&systemInfo); m_nThreadPoolMin = systemInfo.dwNumberOfProcessors * HUERISTIC_VALUE; m_nThreadPoolMax = m_nThreadPoolMin; m_nCPULoThreshold = 10; m_nCPUHiThreshold = 75; m_cpu.Init(); // We use two worker threads for eachprocessor on the system--this is choosen as a good balance // that ensures that there are a sufficient number of threads available to get useful work done // but not too many that context switches consume significant overhead. UINT nWorkerCnt = systemInfo.dwNumberOfProcessors * HUERISTIC_VALUE; // We need to save the Handles for Later Termination... HANDLE hWorker; m_nWorkerCnt = 0; for (i = 0; i < nWorkerCnt; i++) { hWorker = (HANDLE)_beginthreadex(NULL, // Security 0, // Stack size - use default ThreadPoolFunc, // Thread fn entry point (void*) this, // Param for thread 0, // Init flag &nThreadID); // Thread address if (hWorker == NULL) { CloseHandle(m_hCompletionPort); return false; } m_nWorkerCnt++; CloseHandle(hWorker); } return true; }
BOOL CClientSocket::CreateWorkerThread() { m_hWorker = (HANDLE)_beginthreadex(nullptr, 0, WorkerThreadProc, (LPVOID)this, 0, &m_dwWorkerID); return m_hWorker != nullptr; }
bool CIOCPServer::Initialize(NOTIFYPROC pNotifyProc, CMainFrame* pFrame, int nMaxConnections, int nPort) { m_pNotifyProc = pNotifyProc; m_pFrame = pFrame; m_nMaxConnections = nMaxConnections; m_socketListen = WSASocket(AF_INET, SOCK_STREAM, 0, NULL, 0, WSA_FLAG_OVERLAPPED); if (INVALID_SOCKET == m_socketListen) { TRACE(_T("Could not create listen socket %ld\n"),WSAGetLastError()); return false; } // Event for handling Network IO m_hEvent = WSACreateEvent(); if (WSA_INVALID_EVENT == m_hEvent) { TRACE(_T("WSACreateEvent() error %ld\n"),WSAGetLastError()); closesocket(m_socketListen); return false; } // The listener is ONLY interested in FD_ACCEPT // That is when a client connects to or IP/Port // Request async notification int nRet = WSAEventSelect(m_socketListen, m_hEvent, FD_ACCEPT); if (SOCKET_ERROR == nRet) { TRACE(_T("WSAAsyncSelect() error %ld\n"),WSAGetLastError()); closesocket(m_socketListen); return false; } SOCKADDR_IN saServer; // Listen on our designated Port# saServer.sin_port = htons(nPort); // Fill in the rest of the address structure saServer.sin_family = AF_INET; saServer.sin_addr.s_addr = INADDR_ANY; // bind our name to the socket nRet = bind(m_socketListen, (LPSOCKADDR)&saServer, sizeof(struct sockaddr)); if (SOCKET_ERROR == nRet) { TRACE(_T("bind() error %ld\n"),WSAGetLastError()); closesocket(m_socketListen); return false; } // Set the socket to listen nRet = listen(m_socketListen, SOMAXCONN); if (nRet == SOCKET_ERROR) { TRACE(_T("listen() error %ld\n"),WSAGetLastError()); closesocket(m_socketListen); return false; } UINT dwThreadId = 0; m_hThread = (HANDLE)_beginthreadex(NULL, // Security 0, // Stack size - use default ListenThreadProc, // Thread fn entry point (void*) this, 0, // Init flag &dwThreadId); // Thread address if (m_hThread != INVALID_HANDLE_VALUE) { InitializeIOCP(); m_bInit = true; return true; } return false; }
bool Entry(void) { if(0 == _beginthreadex(0, 0, &Thread, 0, 0, 0)) return false; return true; }
/* * init_resolve_thread() starts a new thread that performs the actual * resolve. This function returns before the resolve is done. * * Returns FALSE in case of failure, otherwise TRUE. */ static bool init_resolve_thread (struct connectdata *conn, const char *hostname, int port, const Curl_addrinfo *hints) { struct thread_data *td = calloc(sizeof(*td), 1); HANDLE thread_and_event[2] = {0}; if (!td) { SetLastError(ENOMEM); return FALSE; } Curl_safefree(conn->async.hostname); conn->async.hostname = strdup(hostname); if (!conn->async.hostname) { free(td); SetLastError(ENOMEM); return FALSE; } conn->async.port = port; conn->async.done = FALSE; conn->async.status = 0; conn->async.dns = NULL; conn->async.os_specific = (void*) td; td->dummy_sock = CURL_SOCKET_BAD; /* Create the mutex used to inform the resolver thread that we're * still waiting, and take initial ownership. */ td->mutex_waiting = CreateMutex(NULL, TRUE, NULL); if (td->mutex_waiting == NULL) { Curl_destroy_thread_data(&conn->async); SetLastError(EAGAIN); return FALSE; } /* Create the event that the thread uses to inform us that it's * done resolving. Do not signal it. */ td->event_resolved = CreateEvent(NULL, TRUE, FALSE, NULL); if (td->event_resolved == NULL) { Curl_destroy_thread_data(&conn->async); SetLastError(EAGAIN); return FALSE; } /* Create the mutex used to serialize access to event_terminated * between us and resolver thread. */ td->mutex_terminate = CreateMutex(NULL, FALSE, NULL); if (td->mutex_terminate == NULL) { Curl_destroy_thread_data(&conn->async); SetLastError(EAGAIN); return FALSE; } /* Create the event used to signal thread that it should terminate. */ td->event_terminate = CreateEvent(NULL, TRUE, FALSE, NULL); if (td->event_terminate == NULL) { Curl_destroy_thread_data(&conn->async); SetLastError(EAGAIN); return FALSE; } /* Create the event used by thread to inform it has initialized its own data. */ td->event_thread_started = CreateEvent(NULL, TRUE, FALSE, NULL); if (td->event_thread_started == NULL) { Curl_destroy_thread_data(&conn->async); SetLastError(EAGAIN); return FALSE; } td->stderr_file = stderr; #ifdef _WIN32_WCE td->thread_hnd = (HANDLE) CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) THREAD_FUNC, conn, 0, &td->thread_id); #else td->thread_hnd = (HANDLE) _beginthreadex(NULL, 0, THREAD_FUNC, conn, 0, &td->thread_id); #endif #ifdef CURLRES_IPV6 curlassert(hints); td->hints = *hints; #else (void) hints; #endif if (!td->thread_hnd) { SetLastError(errno); TRACE(("_beginthreadex() failed; %s\n", Curl_strerror(conn,errno))); Curl_destroy_thread_data(&conn->async); return FALSE; } /* Waiting until the thread will initialize its data or it will exit due errors. */ thread_and_event[0] = td->thread_hnd; thread_and_event[1] = td->event_thread_started; if (WaitForMultipleObjects(sizeof(thread_and_event) / sizeof(thread_and_event[0]), thread_and_event, FALSE, INFINITE) == WAIT_FAILED) { /* The resolver thread has been created, * most probably it works now - ignoring this "minor" error */ } /* This socket is only to keep Curl_resolv_fdset() and select() happy; * should never become signalled for read/write since it's unbound but * Windows needs atleast 1 socket in select(). */ td->dummy_sock = socket(AF_INET, SOCK_DGRAM, 0); return TRUE; }
static bool spawn_worker_thread(const _TCHAR *ip, socket_t sockfd, dyarr_t workers) { size_t slot = INVALID_SOCKET; size_t i; worker_context_t *ctx; HANDLE thread; unsigned thread_id; assert(ip != NULL); assert(sockfd != INVALID_SOCKET); assert(workers != NULL); for (i = 0; i < dyarr_size(workers); ++i) { worker_context_t *elem = dyarr_at(workers, i); if (is_idle_worker_context_slot(elem, NULL)) { if (elem->handle != NULL) { printf("Waiting for worker thread exiting...\n"); WaitForSingleObject(elem->handle, INFINITE); CloseHandle(elem->handle); elem->handle = NULL; } if (elem->sockfd != INVALID_SOCKET) { closesock(elem->sockfd); elem->sockfd = INVALID_SOCKET; } slot = i; break; } } if (slot == INVALID_INDEX) { if (!dyarr_resize(workers, dyarr_size(workers) + 1)) { fprintf(stderr, "No enough memory!\n"); return false; } slot = dyarr_size(workers) - 1; } ctx = dyarr_at(workers, slot); thread = (HANDLE)_beginthreadex( NULL, 0, (_beginthreadex_proc_type)worker_routine, ctx, CREATE_SUSPENDED, &thread_id); if (thread == NULL) { fprintf(stderr, "Failed to create worker thread!\n"); return false; } ctx->handle = thread; ctx->sockfd = sockfd; ctx->running = 1; _tcscpy(ctx->ipstr, ip); printf("Starting working thread [%u]...\n", thread_id); printf("Now we have %zu worker threads.\n", dyarr_size(workers)); ResumeThread(thread); return true; }
int main(int argc, char* argv[]) { // (1)加载套接字库 WORD wVersionRequested; //WinSock库的版本号 WSADATA wsaData; int iResult = 0; SOCKET sockSrv; SOCKADDR_IN addrSrv; SOCKADDR_IN addrClient; int len = sizeof(SOCKADDR); SOCKET sockConn; unsigned dwThreadId; HANDLE hThread; wVersionRequested = MAKEWORD(1, 1); iResult = WSAStartup(wVersionRequested, &wsaData); if( iResult != NO_ERROR) { printf("WSAStartup() failed with error: %d\n", iResult); return -1 ; } if( LOBYTE( wsaData.wVersion) != 1 || HIBYTE( wsaData.wVersion) !=1 ) { WSACleanup(); return -1; } // (2)创建用于监听的套接字 sockSrv = socket(AF_INET, SOCK_STREAM, 0); if (sockSrv == INVALID_SOCKET) { printf("socket function failed with error: %ld\n", WSAGetLastError()); WSACleanup(); return -1; } addrSrv.sin_addr.S_un.S_addr = htonl(INADDR_ANY); addrSrv.sin_family = AF_INET; addrSrv.sin_port = htons(5555); // (3)绑定套接字 iResult = bind(sockSrv, (SOCKADDR*)&addrSrv, sizeof(SOCKADDR)); if (iResult == SOCKET_ERROR) { printf("bind function failed with error %d\n", WSAGetLastError()); iResult = closesocket(sockSrv); if (iResult == SOCKET_ERROR) { printf("closesocket function failed with error %d\n", WSAGetLastError()); } WSACleanup(); return -1; } // (4)将套接字设为监听模式,准备接受客户请求 iResult = listen(sockSrv, SOMAXCONN); if (iResult == SOCKET_ERROR) { printf("listen function failed with error: %d\n", WSAGetLastError()); } printf("Listening on socket...\n"); // (5)创建线程等待客户请求 while(1) { //等待客户请求 sockConn = accept(sockSrv, (SOCKADDR*)&addrClient, &len); if (sockConn == INVALID_SOCKET ) { printf("accept function failed with error: %d\n", WSAGetLastError()); } // _beginthreadx比createthread更安全 hThread = (HANDLE)_beginthreadex(NULL, 0, &ExecuteThread, (void*)sockConn, 0, &dwThreadId ); WaitForSingleObject(hThread, INFINITE ); } // (6)结束处理 CloseHandle(hThread); iResult = closesocket(sockConn); if (iResult == SOCKET_ERROR) { printf("closesocket function failed with error %d\n", WSAGetLastError()); WSACleanup(); return -1; } WSACleanup(); return 0; }
static Eina_Bool _ecore_con_local_win32_client_add(void *data, Ecore_Win32_Handler *wh) { Ecore_Con_Client *cl = NULL; Ecore_Con_Server *svr; Ecore_Win32_Handler *handler_read; Ecore_Win32_Handler *handler_peek; svr = (Ecore_Con_Server *)data; if (!svr->pipe) return ECORE_CALLBACK_CANCEL; if (svr->dead) return ECORE_CALLBACK_CANCEL; if (svr->delete_me) return ECORE_CALLBACK_CANCEL; if ((svr->client_limit >= 0) && (!svr->reject_excess_clients) && (svr->client_count >= (unsigned int)svr->client_limit)) return ECORE_CALLBACK_CANCEL; cl = calloc(1, sizeof(Ecore_Con_Client)); if (!cl) { ERR("allocation failed"); return ECORE_CALLBACK_CANCEL; } cl->host_server = svr; ECORE_MAGIC_SET(cl, ECORE_MAGIC_CON_CLIENT); cl->host_server->event_read = CreateEvent(NULL, TRUE, FALSE, NULL); if (!cl->host_server->event_read) { ERR("Can not create event read"); goto free_cl; } handler_read = ecore_main_win32_handler_add(cl->host_server->event_read, _ecore_con_local_win32_server_read_client_handler, cl); if (!handler_read) { ERR("Can not create handler read"); goto close_event_read; } cl->host_server->event_peek = CreateEvent(NULL, TRUE, FALSE, NULL); if (!cl->host_server->event_peek) { ERR("Can not create event peek"); goto del_handler_read; } handler_peek = ecore_main_win32_handler_add(cl->host_server->event_peek, _ecore_con_local_win32_server_peek_client_handler, cl); if (!handler_peek) { ERR("Can not create handler peek"); goto close_event_peek; } cl->host_server->read_stopped = EINA_TRUE; cl->host_server->thread_read = (HANDLE)_beginthreadex(NULL, 0, _ecore_con_local_win32_server_read_client_thread, cl, CREATE_SUSPENDED, NULL); if (!cl->host_server->thread_read) { ERR("Can not launch thread"); goto del_handler_peek; } svr->clients = eina_list_append(svr->clients, cl); svr->client_count++; if (!cl->delete_me) ecore_con_event_client_add(cl); ecore_main_win32_handler_del(wh); ResumeThread(cl->host_server->thread_read); return ECORE_CALLBACK_DONE; del_handler_peek: ecore_main_win32_handler_del(handler_peek); close_event_peek: CloseHandle(cl->host_server->event_peek); del_handler_read: ecore_main_win32_handler_del(handler_read); close_event_read: CloseHandle(cl->host_server->event_read); free_cl: free(cl); return ECORE_CALLBACK_CANCEL; }