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.
186 lines
4.9 KiB
186 lines
4.9 KiB
//+-------------------------------------------------------------------------
|
|
//
|
|
// Microsoft Windows
|
|
// Copyright (C) Microsoft Corporation, 1992 - 1992.
|
|
//
|
|
// File: thread.hxx
|
|
//
|
|
// Contents: Job scheduler worker thread class definition.
|
|
//
|
|
// Classes: CWorkerThread
|
|
//
|
|
// Functions: None.
|
|
//
|
|
// History: 25-Oct-95 MarkBl Created
|
|
// 15-Feb-01 Jbenton Bug 315702 - Increase initial stack size
|
|
// for worker threads
|
|
//
|
|
//--------------------------------------------------------------------------
|
|
|
|
#ifndef __THREAD_HXX__
|
|
#define __THREAD_HXX__
|
|
|
|
class CWorkerThread;
|
|
|
|
#define WORKER_STACK_SIZE 8192
|
|
|
|
|
|
//+-------------------------------------------------------------------------
|
|
//
|
|
// Class: WorkerThread
|
|
//
|
|
// Purpose: Encapsulates the functions of a worker thread. A worker
|
|
// thread is a thread within the job scheduler that is capable
|
|
// of being scheduled to perform various tasks.
|
|
//
|
|
// Notes: None.
|
|
//
|
|
//--------------------------------------------------------------------------
|
|
|
|
class CWorkerThread : public CDLink
|
|
{
|
|
public:
|
|
|
|
CWorkerThread() : _hThread(NULL), _hWorkAvailable(NULL), _pTask(NULL) {
|
|
TRACE3(CWorkerThread, CWorkerThread);
|
|
// Initialize() completes remaining initialization.
|
|
}
|
|
|
|
~CWorkerThread();
|
|
|
|
HRESULT AssignTask(CTask * pTask);
|
|
|
|
HANDLE GetHandle(void) const { return(_hThread); }
|
|
|
|
HRESULT Initialize(void);
|
|
|
|
CWorkerThread * Next(void) { return((CWorkerThread *)CDLink::Next()); }
|
|
|
|
CWorkerThread * Prev(void) { return((CWorkerThread *)CDLink::Prev()); }
|
|
|
|
HRESULT StartWorking(void);
|
|
|
|
private:
|
|
|
|
HANDLE _hThread;
|
|
HANDLE _hWorkAvailable;
|
|
CTask * _pTask;
|
|
};
|
|
|
|
//+-------------------------------------------------------------------------
|
|
//
|
|
// Class: CWorkerThreadQueue
|
|
//
|
|
// Purpose: Queue of CWorkerThread.
|
|
//
|
|
// Notes: None.
|
|
//
|
|
//--------------------------------------------------------------------------
|
|
|
|
class CWorkerThreadQueue : public CQueue
|
|
{
|
|
public:
|
|
|
|
CWorkerThreadQueue(void) {
|
|
TRACE3(CWorkerThreadQueue, CWorkerThreadQueue);
|
|
}
|
|
|
|
~CWorkerThreadQueue() {
|
|
TRACE3(CWorkerThreadQueue, ~CWorkerThreadQueue);
|
|
}
|
|
|
|
void AddElement(CWorkerThread * pWrkThrd) {
|
|
schDebugOut((DEB_USER3,
|
|
"CWorkerThreadQueue::AddElement(0x%x) pWrkThrd(0x%x)\n",
|
|
this,
|
|
pWrkThrd));
|
|
CQueue::AddElement(pWrkThrd);
|
|
}
|
|
|
|
CWorkerThread * GetFirstElement(void) {
|
|
TRACE3(CWorkerThreadQueue, GetFirstElement);
|
|
return((CWorkerThread *)CQueue::GetFirstElement());
|
|
}
|
|
|
|
CWorkerThread * RemoveElement(void) {
|
|
TRACE3(CWorkerThreadQueue, RemoveElement);
|
|
return((CWorkerThread *)CQueue::RemoveElement());
|
|
}
|
|
|
|
CWorkerThread * RemoveElement(CWorkerThread * pWrkThrd) {
|
|
schDebugOut((DEB_USER3,
|
|
"CWorkerThreadQueue::RemoveElement(0x%x) pWrkThrd(0x%x)\n",
|
|
this,
|
|
pWrkThrd));
|
|
return((CWorkerThread *)CQueue::RemoveElement(pWrkThrd));
|
|
}
|
|
};
|
|
|
|
//+-------------------------------------------------------------------------
|
|
//
|
|
// Class: CWorkerThreadMgr
|
|
//
|
|
// Purpose: Free worker thread pool management class.
|
|
//
|
|
// Notes: None.
|
|
//
|
|
//--------------------------------------------------------------------------
|
|
|
|
class CWorkerThreadMgr
|
|
{
|
|
public:
|
|
|
|
CWorkerThreadMgr(void)
|
|
: _cThreadCount(0),
|
|
_hThreadTerminationEvent(NULL) {
|
|
TRACE3(CWorkerThreadMgr, CWorkerThreadMgr);
|
|
InitializeCriticalSection(&_csThreadMgrCritSection);
|
|
}
|
|
|
|
~CWorkerThreadMgr();
|
|
|
|
void AddThread(CWorkerThread * pWrkThrd);
|
|
|
|
// The returned count is considered valid only while the service is
|
|
// in a pending service stop state.
|
|
//
|
|
DWORD GetThreadCount(void) { return(_cThreadCount); }
|
|
|
|
BOOL Initialize(void);
|
|
|
|
CWorkerThread * RemoveThread(void);
|
|
|
|
CWorkerThread * RemoveThread(HANDLE hThread);
|
|
|
|
BOOL Shutdown(BOOL fWait);
|
|
|
|
void SignalThreadCreation(void) {
|
|
InterlockedIncrement((LONG *)&_cThreadCount);
|
|
}
|
|
|
|
void SignalThreadTermination(void) {
|
|
InterlockedDecrement((LONG *)&_cThreadCount);
|
|
SetEvent(_hThreadTerminationEvent);
|
|
}
|
|
|
|
private:
|
|
|
|
// Guards this object during multi-threaded access.
|
|
//
|
|
CRITICAL_SECTION _csThreadMgrCritSection;
|
|
|
|
// Queue of free worker threads.
|
|
//
|
|
CWorkerThreadQueue _WorkerThreadQueue;
|
|
|
|
// This count is a superset of the _WorkerThreadQueue count.
|
|
// _gcThreadCount = # busy + # free.
|
|
//
|
|
DWORD _cThreadCount;
|
|
|
|
// Signalled by the worker threads on termination.
|
|
//
|
|
HANDLE _hThreadTerminationEvent;
|
|
};
|
|
|
|
#endif // __THREAD_HXX__
|