BOOL CWaitThreadPools::CreateWaitThread(PVOID pParameter) { if (NULL==m_pPool || NULL==m_pCleanupGroup) return FALSE; PTP_WAIT pWait = CreateThreadpoolWait((PTP_WAIT_CALLBACK)WaitCallback, pParameter, &m_CallBackEnviron); if (NULL==pWait) return FALSE; SetThreadpoolWait(pWait, m_hEvent, NULL); return TRUE; }
bool FileOpLock::BeginLock(const std::wstring& filename, DWORD dwShareMode) { g_hLockCompleted = CreateEvent(nullptr, TRUE, FALSE, nullptr); g_o.hEvent = CreateEvent(nullptr, FALSE, FALSE, nullptr); DWORD flags = FILE_FLAG_OVERLAPPED; if (GetFileAttributesW(filename.c_str()) & FILE_ATTRIBUTE_DIRECTORY) { flags |= FILE_FLAG_BACKUP_SEMANTICS; } g_hFile = CreateFileW(filename.c_str(), GENERIC_READ, dwShareMode, nullptr, OPEN_EXISTING, flags, nullptr); if (g_hFile == INVALID_HANDLE_VALUE) { DebugPrintf("Error opening file: %d\n", GetLastError()); return false; } g_wait = CreateThreadpoolWait(WaitCallback, this, nullptr); if (g_wait == nullptr) { DebugPrintf("Error creating threadpool %d\n", GetLastError()); return false; } SetThreadpoolWait(g_wait, g_o.hEvent, nullptr); DeviceIoControl(g_hFile, FSCTL_REQUEST_OPLOCK, &g_inputBuffer, sizeof(g_inputBuffer), &g_outputBuffer, sizeof(g_outputBuffer), nullptr, &g_o); DWORD err = GetLastError(); if (err != ERROR_IO_PENDING) { DebugPrintf("Oplock Failed %d\n", err); return false; } return true; }
int _tmain1(int argc, _TCHAR* argv[]) { if (depth == 0) { Display("%d(%d)************\n", GetCurrentProcessId(), GetCurrentThreadId()); return 1; } int multiply = 1; if (argc > 2) { multiply = _ttoi(argv[2]); if (multiply < 1) { Display("multiply should be greater than 1\n"); return -2; } } TP_CALLBACK_ENVIRON CallBackEnviron; InitializeThreadpoolEnvironment(&CallBackEnviron); PTP_POOL pool = CreateThreadpool(NULL); if (NULL == pool) { _tprintf(_T("CreateThreadpool failed. LastError: %u\n"), GetLastError()); } SetThreadpoolThreadMaximum(pool, 100); BOOL bRet = SetThreadpoolThreadMinimum(pool, 20); if (!bRet) { _tprintf(_T("SetThreadpoolThreadMinimum failed. LastError: %u\n"), GetLastError()); } PTP_CLEANUP_GROUP cleanupgroup = CreateThreadpoolCleanupGroup(); if (NULL == cleanupgroup) { _tprintf(_T("CreateThreadpoolCleanupGroup failed. LastError: %u\n"), GetLastError()); } SetThreadpoolCallbackPool(&CallBackEnviron, pool); SetThreadpoolCallbackCleanupGroup(&CallBackEnviron, cleanupgroup, NULL); struct ProcSetup { PROCESS_INFORMATION pi; HANDLE hEvent; HANDLE hWait; HANDLE hOutputRead; HANDLE hErrorRead; HANDLE hInputWrite; int rc; ProcSetup(PROCESS_INFORMATION _pi, HANDLE _hEvent, HANDLE _hWait, HANDLE _hOutputRead, HANDLE _hErrorRead, HANDLE _hInputWrite) : pi(_pi), hEvent(_hEvent), hWait(_hWait), hOutputRead(_hOutputRead), hErrorRead(_hErrorRead), hInputWrite(_hInputWrite) {} }; ProcSetup* pss = (ProcSetup*)calloc(multiply, sizeof(ProcSetup)); for (int i = 0; i < multiply; i++) { Display("%d(%d) Multiply %d out of %d\n", GetCurrentProcessId(), GetCurrentThreadId(), i, multiply); HANDLE hOutputRead, hOutputWrite; HANDLE hErrorRead, hErrorWrite; HANDLE hInputRead, hInputWrite; SECURITY_ATTRIBUTES sa; // Set up the security attributes struct. sa.nLength= sizeof(SECURITY_ATTRIBUTES); sa.lpSecurityDescriptor = NULL; sa.bInheritHandle = TRUE; STARTUPINFO startup_info; ZeroMemory(&startup_info, sizeof(startup_info)); startup_info.cb = sizeof(startup_info); startup_info.dwFlags = STARTF_USESTDHANDLES; PROCESS_INFORMATION process_info; ZeroMemory(&process_info, sizeof(process_info)); TCHAR cmd[1024]; _stprintf(cmd, _T("%s %d"), argv[0], depth-1); BOOL result = CreateProcess(NULL, // ApplicationName cmd, NULL, // ProcessAttributes NULL, // ThreadAttributes TRUE, // InheritHandles CREATE_SUSPENDED, // | CREATE_BREAKAWAY_FROM_JOB, // CreationFlags NULL, NULL, &startup_info, &process_info); pss[i].hEvent = CreateEvent(NULL, TRUE, FALSE, NULL); pss[i].pi = process_info; PTP_WAIT myWait = CreateThreadpoolWait(callback, new WaiterParams(process_info, pss[i].hEvent, &pss[i].rc), &CallBackEnviron); SetThreadpoolWait(myWait, process_info.hProcess, NULL); ResumeThread(process_info.hThread); } HANDLE* events = (HANDLE*)calloc(multiply, sizeof(HANDLE)); for (int i = 0; i < multiply; i++) { events[i] = pss[i].hEvent; } WaitForMultipleObjects(multiply, events, true, INFINITE); int exit_code; for (int i = 0; i < multiply; i++) { PROCESS_INFORMATION* process_info = &pss[i].pi; int texit_code; BOOL ok = GetExitCodeThread(process_info->hThread, reinterpret_cast<DWORD*>(&texit_code)); if (!ok) { printf("*** GetExitCodeThread failed %d\n", GetLastError()); } ok = GetExitCodeProcess(process_info->hProcess, reinterpret_cast<DWORD*>(&exit_code)); if (!ok) { printf("*** GetExitCodeProcess failed %d\n", GetLastError()); } if (texit_code != exit_code) { printf("*** Thread %d exit code %x didn't match process %d exit code %x\n", process_info->dwThreadId, texit_code, process_info->dwProcessId, exit_code); } CloseHandle(process_info->hProcess); CloseHandle(process_info->hThread); // *wp->pRC = exit_code; // exit_code = pss[i].rc; if (exit_code != 1) { printf("Failed to get correct exit code. Got %d instead\n", exit_code); } } for (int i = 0; i < multiply; i++) { CloseHandle(pss[i].hEvent); } free(events); CloseThreadpoolCleanupGroupMembers(cleanupgroup, FALSE, NULL); CloseThreadpoolCleanupGroup(cleanupgroup); CloseThreadpool(pool); DestroyThreadpoolEnvironment(&CallBackEnviron); return exit_code; }