void CThreadPools::CreateThreadPools(int nThreadCount)
{
	BOOL bRet = FALSE;

	InitializeThreadpoolEnvironment(&m_CallBackEnviron);

	// Create a custom, dedicated thread pool
	m_pPool = CreateThreadpool(NULL);

	if (NULL==m_pPool) 
	{
		CloseThreadPools();
	}

	m_nRollback = 1; // pool creation succeeded

	// The thread pool is made persistent simply by setting
	// both the minimum and maximum threads to 1.
	SetThreadpoolThreadMaximum(m_pPool, nThreadCount);

	bRet = SetThreadpoolThreadMinimum(m_pPool, 1);

	if (FALSE==bRet) 
	{
		CloseThreadPools();
	}

	//Create a cleanup group for this thread pool
	m_pCleanupGroup = CreateThreadpoolCleanupGroup();

	if (NULL==m_pCleanupGroup) 
	{
		CloseThreadPools(); 
	}

	m_nRollback = 2;  // Cleanup group creation succeeded

	// Associate the callback environment with our thread pool.
	SetThreadpoolCallbackPool(&m_CallBackEnviron, m_pPool);

	// Associate the cleanup group with our thread pool.
	// Objects created with the same callback environment
	// as the cleanup group become members of the cleanup group.
	SetThreadpoolCallbackCleanupGroup(&m_CallBackEnviron, m_pCleanupGroup, NULL);

	m_nRollback = 3;  // Creation of work succeeded

}
bool test_new_thread_pool() {//success is true, failure is false
	int sockErr;

	WSADATA lpWSAData={0};
	sockErr=WSAStartup(0x202, &lpWSAData);
	sListen=WSASocket(AF_INET, SOCK_STREAM, IPPROTO_TCP, NULL, 0, WSA_FLAG_OVERLAPPED);
	if(INVALID_SOCKET==sListen){
		DebugBreak();
	}
	GUID GuidDisconnectEx = WSAID_DISCONNECTEX;
	DWORD dwBytes;
	WSAIoctl(sListen, SIO_GET_EXTENSION_FUNCTION_POINTER,
             &GuidDisconnectEx, sizeof (GuidDisconnectEx), 
             &DisconnectEx, sizeof (DisconnectEx), 
             &dwBytes, NULL, NULL);
	

	InitializeThreadpoolEnvironment(&tEnvrion);
	pMainPool=CreateThreadpool(NULL);
	pCleanup=CreateThreadpoolCleanupGroup();
	SetThreadpoolCallbackCleanupGroup(&tEnvrion, pCleanup, 0);
	SetThreadpoolCallbackPool(&tEnvrion, pMainPool);

	pListen=CreateThreadpoolIo((HANDLE)sListen, acceptingIoThreadProc, 0, &tEnvrion);

	sockaddr_in service={0};
	service.sin_family=AF_INET;
	service.sin_port=htons(8080);

	sockErr=bind(sListen, (SOCKADDR *) &service, sizeof(service));
	if(SOCKET_ERROR==sockErr){
		DebugBreak();
	}
	sockErr=listen(sListen, SOMAXCONN);
	if(SOCKET_ERROR==sockErr){
		DebugBreak();
	}
	for(int i=0; i<numSockets; i++){
		ntpAddAcceptSocket(sListen);
	}
	OutputDebugString(TEXT("CloseThreadpoolCleanupGroupMembers waiting\n"));
	SleepEx(INFINITE, TRUE);
	CloseThreadpoolCleanupGroupMembers(pCleanup, FALSE, NULL);
	OutputDebugString(TEXT("CloseThreadpoolCleanupGroupMembers done\n"));
	
	return false;
}
UINT32 HlprThreadPoolDataPopulate(_Inout_ THREADPOOL_DATA* pThreadPoolData,
                                  _In_ const PTP_CLEANUP_GROUP_CANCEL_CALLBACK pGroupCancelFn)
{
   ASSERT(pThreadPoolData);

   UINT32 status = NO_ERROR;

   InitializeThreadpoolEnvironment(&(pThreadPoolData->callbackEnvironment));

   pThreadPoolData->pThreadPool = CreateThreadpool(0);
   if(pThreadPoolData->pThreadPool == 0)
   {
      status = GetLastError();

      HlprLogError(L"HlprThreadPoolDataPopulate : CreateThreadPool() [status: %#x]",
                   status);

      HLPR_BAIL;
   }

   pThreadPoolData->pCleanupGroup = CreateThreadpoolCleanupGroup();
   if(pThreadPoolData->pCleanupGroup == 0)
   {
      status = GetLastError();

      HlprLogError(L"HlprThreadPoolDataPopulate : CreateThreadPool() [status: %#x]",
                   status);

      HLPR_BAIL;
   }  

   SetThreadpoolCallbackPool(&(pThreadPoolData->callbackEnvironment),
                             pThreadPoolData->pThreadPool);

   SetThreadpoolCallbackCleanupGroup(&(pThreadPoolData->callbackEnvironment),
                                     pThreadPoolData->pCleanupGroup,
                                     pGroupCancelFn);

   HLPR_BAIL_LABEL:

   if(status != NO_ERROR)
      HlprThreadPoolDataPurge(pThreadPoolData);

   return status;
}
__declspec(noinline) bool benchmark_ntp_fs_stat() {
	TP_CALLBACK_ENVIRON env;
	InitializeThreadpoolEnvironment(&env);

	PTP_POOL pool{nullptr};
	pool = CreateThreadpool(nullptr);
	SetThreadpoolThreadMaximum(pool, 48);
	SetThreadpoolThreadMinimum(pool, 12);

	PTP_CLEANUP_GROUP group = CreateThreadpoolCleanupGroup();
	SetThreadpoolCallbackPool(&env, pool);
	SetThreadpoolCallbackCleanupGroup(&env, group, nullptr);

	PTP_WORK work_fs_stat = CreateThreadpoolWork(WorkCallback_fs_stat, nullptr, &env);


	SubmitThreadpoolWork(work_fs_stat);
	WaitForThreadpoolWorkCallbacks(work_fs_stat, false);

	CloseThreadpoolWork(work_fs_stat);

	CloseThreadpool(pool);
	return false;
}
Beispiel #5
0
bool Server::Create(short port, int maxPostAccept)
{
    assert(maxPostAccept > 0);

    m_MaxPostAccept = maxPostAccept;

    // Create Client Work Thread Env for using cleaning group. We need this for shutting down
    // properly.
    InitializeThreadpoolEnvironment(&m_ClientTPENV);
    m_ClientTPCLEAN = CreateThreadpoolCleanupGroup();
    if (m_ClientTPCLEAN == NULL)
    {
        ERROR_CODE(GetLastError(), "Could not create client cleaning group.");
        return false;
    }
    SetThreadpoolCallbackCleanupGroup(&m_ClientTPENV, m_ClientTPCLEAN, NULL);

    // Create Listen Socket
    m_listenSocket = Network::CreateSocket(true, port);
    if (m_listenSocket == INVALID_SOCKET)
    {
        return false;
    }

    // Make the address re-usable to re-run the same server instantly.
    bool reuseAddr = true;
    if (setsockopt(m_listenSocket, SOL_SOCKET, SO_REUSEADDR,
                   reinterpret_cast<const char*>(&reuseAddr), sizeof(reuseAddr)) == SOCKET_ERROR)
    {
        ERROR_CODE(WSAGetLastError(), "setsockopt() failed with SO_REUSEADDR.");
        Destroy();
        return false;
    }

    // Create & Start ThreaddPool for socket IO
    m_pTPIO = CreateThreadpoolIo(reinterpret_cast<HANDLE>(m_listenSocket),
                                 Server::IoCompletionCallback, NULL, NULL);
    if (m_pTPIO == NULL)
    {
        ERROR_CODE(WSAGetLastError(), "Could not assign the listen socket to the IOCP handle.");
        Destroy();
        return false;
    }

    // Start listening
    StartThreadpoolIo(m_pTPIO);
    if (listen(m_listenSocket, SOMAXCONN) == SOCKET_ERROR)
    {
        ERROR_CODE(WSAGetLastError(), "listen() failed.");
        return false;
    }

    // Create critical sections for m_Clients
    InitializeCriticalSection(&m_CSForClients);

    // Create Accept worker
    m_AcceptTPWORK = CreateThreadpoolWork(Server::WorkerPostAccept, this, NULL);
    if (m_AcceptTPWORK == NULL)
    {
        ERROR_CODE(GetLastError(), "Could not create AcceptEx worker TPIO.");
        Destroy();
        return false;
    }

    m_ShuttingDown = false;

    SubmitThreadpoolWork(m_AcceptTPWORK);

    return true;
}
Beispiel #6
0
int TestPoolWork(int argc, char* argv[])
{
	int index;
	PTP_POOL pool;
	PTP_WORK work;
	PTP_CLEANUP_GROUP cleanupGroup;
	TP_CALLBACK_ENVIRON environment;

	printf("Global Thread Pool\n");

	work = CreateThreadpoolWork((PTP_WORK_CALLBACK) test_WorkCallback, "world", NULL);

	if (!work)
	{
		printf("CreateThreadpoolWork failure\n");
		return -1;
	}

	/**
	 * You can post a work object one or more times (up to MAXULONG) without waiting for prior callbacks to complete.
	 * The callbacks will execute in parallel. To improve efficiency, the thread pool may throttle the threads.
	 */

	for (index = 0; index < 10; index++)
		SubmitThreadpoolWork(work);

	WaitForThreadpoolWorkCallbacks(work, FALSE);
	CloseThreadpoolWork(work);

	printf("Private Thread Pool\n");

	if (!(pool = CreateThreadpool(NULL)))
	{
		printf("CreateThreadpool failure\n");
		return -1;
	}

	if (!SetThreadpoolThreadMinimum(pool, 4))
	{
		printf("SetThreadpoolThreadMinimum failure\n");
		return -1;
	}

	SetThreadpoolThreadMaximum(pool, 8);

	InitializeThreadpoolEnvironment(&environment);
	SetThreadpoolCallbackPool(&environment, pool);

	cleanupGroup = CreateThreadpoolCleanupGroup();

	if (!cleanupGroup)
	{
		printf("CreateThreadpoolCleanupGroup failure\n");
		return -1;
	}

	SetThreadpoolCallbackCleanupGroup(&environment, cleanupGroup, NULL);

	work = CreateThreadpoolWork((PTP_WORK_CALLBACK) test_WorkCallback, "world", &environment);

	if (!work)
	{
		printf("CreateThreadpoolWork failure\n");
		return -1;
	}

	for (index = 0; index < 10; index++)
		SubmitThreadpoolWork(work);

	WaitForThreadpoolWorkCallbacks(work, FALSE);

	CloseThreadpoolCleanupGroupMembers(cleanupGroup, TRUE, NULL);

	CloseThreadpoolCleanupGroup(cleanupGroup);

	DestroyThreadpoolEnvironment(&environment);

	/**
	 * See Remarks at https://msdn.microsoft.com/en-us/library/windows/desktop/ms682043(v=vs.85).aspx
	 * If there is a cleanup group associated with the work object,
	 * it is not necessary to call CloseThreadpoolWork !
	 * calling the CloseThreadpoolCleanupGroupMembers function releases the work, wait,
	 * and timer objects associated with the cleanup group.
	 */

	/* CloseThreadpoolWork(work); // this would segfault, see comment above. */

	CloseThreadpool(pool);

	return 0;
}
Beispiel #7
0
int TestPoolWork(int argc, char* argv[])
{
	int index;
	PTP_POOL pool;
	PTP_WORK work;
	PTP_CLEANUP_GROUP cleanupGroup;
	TP_CALLBACK_ENVIRON environment;

	printf("Global Thread Pool\n");

	work = CreateThreadpoolWork((PTP_WORK_CALLBACK) test_WorkCallback, "world", NULL);

	if (!work)
	{
		printf("CreateThreadpoolWork failure\n");
		return -1;
	}

	/**
	 * You can post a work object one or more times (up to MAXULONG) without waiting for prior callbacks to complete.
	 * The callbacks will execute in parallel. To improve efficiency, the thread pool may throttle the threads.
	 */

	for (index = 0; index < 10; index++)
		SubmitThreadpoolWork(work);

	WaitForThreadpoolWorkCallbacks(work, FALSE);
	CloseThreadpoolWork(work);

	printf("Private Thread Pool\n");

	pool = CreateThreadpool(NULL);

	SetThreadpoolThreadMinimum(pool, 4);
	SetThreadpoolThreadMaximum(pool, 8);

	InitializeThreadpoolEnvironment(&environment);
	SetThreadpoolCallbackPool(&environment, pool);

	cleanupGroup = CreateThreadpoolCleanupGroup();

	if (!cleanupGroup)
	{
		printf("CreateThreadpoolCleanupGroup failure\n");
		return -1;
	}

	SetThreadpoolCallbackCleanupGroup(&environment, cleanupGroup, NULL);

	work = CreateThreadpoolWork((PTP_WORK_CALLBACK) test_WorkCallback, "world", &environment);

	if (!work)
	{
		printf("CreateThreadpoolWork failure\n");
		return -1;
	}

	for (index = 0; index < 10; index++)
		SubmitThreadpoolWork(work);

	WaitForThreadpoolWorkCallbacks(work, FALSE);

	CloseThreadpoolCleanupGroupMembers(cleanupGroup, TRUE, NULL);

	CloseThreadpoolCleanupGroup(cleanupGroup);

	DestroyThreadpoolEnvironment(&environment);

	CloseThreadpoolWork(work);
	CloseThreadpool(pool);

	return 0;
}
//
// This function is invoked only with Airplane mode change, but not with NFC radio state change.
//
STDMETHODIMP CNfcRadioManager::OnSystemRadioStateChange(
        _In_opt_ SYSTEM_RADIO_STATE sysRadioState,
        _In_ UINT32 uTimeoutSec)
{
    UNREFERENCED_PARAMETER(sysRadioState);
    UNREFERENCED_PARAMETER(uTimeoutSec);

    TRACE_METHOD_ENTRY(LEVEL_VERBOSE);

    HRESULT hr = S_OK;
    PTP_POOL threadPool = NULL;
    TP_CALLBACK_ENVIRON callbackEnviron;
    PTP_CLEANUP_GROUP ptpCleanupGroup = NULL;
    
    // Create threadpool to handle all of the radios
    threadPool = CreateThreadpool(NULL);
    if (NULL == threadPool)
    {
        hr = HRESULT_FROM_WIN32(GetLastError());
    }

    if (SUCCEEDED(hr))
    {
        SetThreadpoolThreadMaximum(threadPool, 50);
        InitializeThreadpoolEnvironment(&callbackEnviron);
        SetThreadpoolCallbackPool(&callbackEnviron, threadPool);
        ptpCleanupGroup = CreateThreadpoolCleanupGroup();

        if (NULL == ptpCleanupGroup)
        {
            hr = HRESULT_FROM_WIN32(GetLastError());
        }
        else
        {
            // Associate the cleanup group with our thread pool
            SetThreadpoolCallbackCleanupGroup(&callbackEnviron,
                                                ptpCleanupGroup,
                                                NULL );
        }
    }

    // Lock so that any adds or removes will not cause list changes during system airplane mode
    EnterCriticalSection(&m_csAddRemoveLock);

    if (SUCCEEDED(hr))
    {
        UINT32 i, count = 0;
        SYSTEM_STATE_SWITCH_CONTEXT* pContext = NULL;

        hr = m_nfcRadioCollection->GetCount(&count);

        if (count > 0)
        {
            if (SUCCEEDED(hr))
            {
                pContext = (SYSTEM_STATE_SWITCH_CONTEXT*)malloc(count * sizeof(SYSTEM_STATE_SWITCH_CONTEXT));
                if (NULL == pContext)
                {
                    hr = E_OUTOFMEMORY;
                }
            }
            
            for (i = 0; (SUCCEEDED(hr) && (i < count)); i++)
            {
                PTP_WORK ptpThreadWork = NULL;
                
                pContext[i].sysRadioState = sysRadioState;
                m_nfcRadioCollection->GetAt(i, (IRadioInstance**)&(pContext[i].pRadioInstance));
                
                ptpThreadWork = CreateThreadpoolWork( 
                                     (PTP_WORK_CALLBACK)&CNfcRadioManager::AsyncRadioChange, 
                                     &(pContext[i]), 
                                     &(callbackEnviron) );
                
                if (ptpThreadWork == NULL)
                {   
                    // pRadioInstance context was not successfully added to threadpool.
                    hr = pContext[i].pRadioInstance->SetSystemState(sysRadioState);
                    pContext[i].pRadioInstance->Release();
                }
                else
                {
                    ::SubmitThreadpoolWork(ptpThreadWork);
                }
            }
        }

        // Wait for all threadpools to drain and clean up threads
        CloseThreadpoolCleanupGroupMembers(ptpCleanupGroup, FALSE, NULL);

        if (NULL != pContext)
        {
            free(pContext);
        }
    }
    else
    {
        // Failed to set up threadpool for parallel system radio change. Only choice is to do it serially now
        UINT32 i, count = 0;
        CNfcRadioInstance* pRadioInstance = NULL;

        hr = m_nfcRadioCollection->GetCount(&count);
        for (i = 0; (SUCCEEDED(hr) && (i < count)); i++)
        {
            hr = m_nfcRadioCollection->GetAt(i, (IRadioInstance**)&pRadioInstance);
            if (SUCCEEDED(hr))
            {
                hr = pRadioInstance->SetSystemState(sysRadioState);
            }
            
            pRadioInstance->Release();
        }
    }

    LeaveCriticalSection(&m_csAddRemoveLock);

    DestroyThreadpoolEnvironment(&callbackEnviron);

    if(ptpCleanupGroup)
    {
        CloseThreadpoolCleanupGroup(ptpCleanupGroup);
        ptpCleanupGroup = NULL;
    }
  
    if(threadPool)
    {
        CloseThreadpool(threadPool);
        threadPool = NULL;
    }

    TRACE_METHOD_EXIT_HR(LEVEL_COND, hr);
    return hr;
}
Beispiel #9
0
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;
}