Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

249 lines
4.8 KiB

/*++
Copyright (c) 1999-2001 Microsoft Corporation
Module Name:
thread_functions.cxx
Abstract:
Public routines for the worker process thread pool
Creates global instance of THREAD_POOL and forwards calls
Author:
Taylor Weiss (TaylorW) 12-Jan-2000
Jeffrey Wall (jeffwall) April 2001
--*/
#include <iis.h>
#include <dbgutil.h>
#include <thread_pool.h>
#include <regconst.h>
//
// Only initialize ourselves once
//
LONG g_cInitializeCount = -1;
//
// global pointer for process thread pool
//
THREAD_POOL * g_pThreadPool = NULL;
/**********************************************************************
Public function definitions
**********************************************************************/
HRESULT
ThreadPoolInitialize( DWORD cbInitialStackSize )
/*++
Routine Description:
Initializes the thread pool.
NO SYNCHRONIZATION HERE
Make sure the initialization of the thread pool is complete (this function returns S_OK)
before calling other public API functions, including this one.
Arguments:
None.
Return Value:
NOERROR if thread pool is initialized
FAILED() otherwise
--*/
{
HRESULT hr = S_OK;
BOOL fRet = FALSE;
if ( InterlockedIncrement( &g_cInitializeCount ) != 0 )
{
//
// Already inited
//
DBGPRINTF(( DBG_CONTEXT,
"W3TP: ThreadPoolInitialize() already called\n" ));
hr = S_OK;
goto done;
}
DBG_ASSERT(NULL == g_pThreadPool);
THREAD_POOL_CONFIG poolConfig;
hr = InitializeThreadPoolConfigWithDefaults(&poolConfig);
if (FAILED(hr))
{
goto done;
}
hr = OverrideThreadPoolConfigWithRegistry(&poolConfig,
REGISTRY_KEY_INETINFO_PARAMETERS_W);
if (FAILED(hr))
{
goto done;
}
fRet = THREAD_POOL::CreateThreadPool(&g_pThreadPool, &poolConfig);
if (FALSE == fRet)
{
hr = E_FAIL;
goto done;
}
DBG_ASSERT(NULL != g_pThreadPool);
hr = S_OK;
done:
return hr;
}
HRESULT
ThreadPoolTerminate( VOID )
/*++
Routine Description:
Cleans up the thread pool. At this point all clients should
have terminated (cleanly we hope) and our threads should
be idle.
Arguments:
None.
Return Value:
NOERROR if clean shutdown
FAILED() otherwise
--*/
{
HRESULT hr = S_OK;
BOOL fRet = FALSE;
if ( InterlockedDecrement( &g_cInitializeCount ) >= 0 )
{
//
// Someone else is using the pool
//
DBGPRINTF(( DBG_CONTEXT,
"W3TP: ThreadPoolTerminate() called but pool still in use\n" ));
hr = S_OK;
goto done;
}
//
// Now we can cleanup!
//
DBG_ASSERT(NULL != g_pThreadPool);
g_pThreadPool->TerminateThreadPool();
g_pThreadPool = NULL;
hr = S_OK;
done:
return hr;
}
BOOL ThreadPoolPostCompletion(
IN DWORD dwBytesTransferred,
IN LPOVERLAPPED_COMPLETION_ROUTINE Function,
IN LPOVERLAPPED lpo
)
/*++
Routine Description:
Posts a completion to the port. Results in an asynchronous callback.
Arguments:
dwBytesTransferred - bytes transferred for this completions
Function - function to call on completion
lpo - overlapped pointer
Return Value:
TRUE if completion posted, otherwise FALSE
--*/
{
DBG_ASSERT(g_pThreadPool);
return g_pThreadPool->PostCompletion(dwBytesTransferred,
Function,
lpo);
}
BOOL
ThreadPoolBindIoCompletionCallback(
HANDLE FileHandle, // handle to file
LPOVERLAPPED_COMPLETION_ROUTINE Function, // callback
ULONG Flags // reserved
)
/*++
Routine Description:
Binds given handle to completion port
Arguments:
FileHandle - handle to bind
Function - function to call on completion
Flags - not used
Return Value:
TRUE if handle bound to port, otherwise FALSE
--*/
{
DBG_ASSERT(g_pThreadPool);
return g_pThreadPool->BindIoCompletionCallback(FileHandle,
Function,
Flags);
}
ULONG_PTR
ThreadPoolSetInfo(
IN THREAD_POOL_INFO InfoId,
IN ULONG_PTR Data
)
/*++
Routine Description:
Sets thread pool configuration data
Arguments:
InfoId - Data item to set
Data - New value for item
Return Value:
The old data value
--*/
{
DBG_ASSERT(g_pThreadPool);
return g_pThreadPool->SetInfo(InfoId, Data);
}