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.
 
 
 
 
 
 

165 lines
4.7 KiB

//+----------------------------------------------------------------------------
//
// Copyright (C) 1997, Microsoft Corporation
//
// File: thrdpool.h
//
// Contents: definitions needed for clients of the thrdpool lib
//
// Description: The thrdpool library defines the CWorkerThread base class
// Users of this lib should define their own derived class
// that inherits from CWorkerThread. Each CWorkerThread object
// has a thread that is used to do some work. It is also
// associated with a common completion port that is used to
// queue work items. All worker threads will normally block on
// GetQueuedCompletionStatus(). Clients of the CWorkerThread
// objects will call PostWork() to get work done. This will
// result in one of the worker threads returning from
// GetQueuedCompletionStatus() and calling the derived class'
// WorkCompletion() routine with a pvContext.
//
// NOTE: the base class has no knowledge of the type of work
// getting done. It just manages the details of getting work
// requests and distributing it to threads in its pool. This
// allows the derived class to focus on processing the actual
// work item without bothering about queueing etc.
//
// Completion ports are used merely to leverage its queueing
// semantics and not for I/O. If the work done by each thread
// is fairly small, LIFO semantics of completion ports will
// reduce context switches.
//
// Functions:
//
// History: 03/15/97 Rajeev Rajan (rajeevr) Created
// 11/11/97 Adapted for DAV usage
//
//-----------------------------------------------------------------------------
#ifndef _THRDPOOL_H_
#define _THRDPOOL_H_
#include <autoptr.h>
#include <singlton.h>
// CPoolManager --------------------------------------------------------------
//
class CDavWorkContext;
class CDavWorkerThread;
class CPoolManager : private Singleton<CPoolManager>
{
//
// Friend declarations required by Singleton template
//
friend class Singleton<CPoolManager>;
private:
// Completion port for WorkerThreads
//
auto_handle<HANDLE> m_hCompletionPort;
// Array of worker threads
//
enum { CTHRD_WORKER = 5 };
CDavWorkerThread * m_rgpdwthrd[CTHRD_WORKER];
// CREATORS
//
// Declared private to ensure that arbitrary instances
// of this class cannot be created. The Singleton
// template (declared as a friend above) controls
// the sole instance of this class.
//
CPoolManager() {}
~CPoolManager();
BOOL FInitPool(DWORD dwConcurrency = CTHRD_WORKER);
VOID TerminateWorkers();
// NOT IMPLEMENTED
//
CPoolManager(const CPoolManager& x);
CPoolManager& operator=(const CPoolManager& x);
public:
// STATICS
//
static BOOL FInit()
{
if ( CreateInstance().FInitPool() )
return TRUE;
DestroyInstance();
return FALSE;
}
static VOID Deinit()
{
DestroyInstance();
}
static BOOL PostWork (CDavWorkContext * pwc);
static BOOL PostDelayedWork (CDavWorkContext * pwc,
DWORD dwMsecDelay);
static HANDLE GetIOCPHandle()
{
return Instance().m_hCompletionPort.get();
}
};
// CDavWorkContext --------------------------------------------------------------
//
// Work context base class for work items posted to the thread pool.
//
// Note: this class is NOT refcounted. Lifetime of work items is determined
// external to the thread pool mechanism. In particular, if a particular
// derived work item class needs to have an indefinite lifetime, it is up
// to the derived class to provide that functionality. E.g. a derived work
// item can have a refcount. Code that posts the work item would then
// add a reference before posting and release the reference (possibly destroying
// the object if is the last ref) in its DwDoWork() call.
//
// The reason for this is that not ALL work items may be refcounted.
// In fact, some may be static....
//
class CDavWorkContext
{
private:
// NOT IMPLEMENTED
//
CDavWorkContext(const CDavWorkContext& x);
CDavWorkContext& operator=(const CDavWorkContext& x);
DWORD m_cbTransferred;
DWORD m_dwLastError;
LPOVERLAPPED m_po;
public:
CDavWorkContext() :
m_cbTransferred(0),
m_dwLastError(ERROR_SUCCESS),
m_po(NULL)
{
}
virtual ~CDavWorkContext() = 0;
virtual DWORD DwDoWork () = 0;
void SetCompletionStatusData(DWORD cbTransferred,
DWORD dwLastError,
LPOVERLAPPED po)
{
m_cbTransferred = cbTransferred;
m_dwLastError = dwLastError;
m_po = po;
}
DWORD CbTransferred() const { return m_cbTransferred; }
DWORD DwLastError() const { return m_dwLastError; }
LPOVERLAPPED GetOverlapped() const { return m_po; }
};
#endif