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.
|
|
///////////////////////////////////////////////////////////////////////////
//
// Copyright(C) 1999 Microsoft Corporation all rights reserved.
//
// Module: workerthread.cpp
//
// Project: Chameleon
//
// Description: Generic Worker Thread Class Implementation
//
// Log:
//
// When Who What
// ---- --- ----
// 02/08/1999 TLP Initial Version
//
///////////////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "workerthread.h"
#include <process.h>
//////////////////////////////////////////////////////////////////////////
//
// Function: Constructor
//
// Synopsis: Initialize the worker thread object
//
//////////////////////////////////////////////////////////////////////////
CTheWorkerThread::CTheWorkerThread() { m_ThreadInfo.bExit = true; m_ThreadInfo.bSuspended = true; m_ThreadInfo.hWait = NULL; m_ThreadInfo.hExit = NULL; m_ThreadInfo.hThread = NULL; m_ThreadInfo.dwThreadId = 0; m_ThreadInfo.dwWaitInterval = 0; m_ThreadInfo.pfnCallback = NULL; }
//////////////////////////////////////////////////////////////////////////
//
// Function: Destructor
//
// Synopsis: Syncronize the destruction of the worker thread with
// the worker thread object.
//
//////////////////////////////////////////////////////////////////////////
CTheWorkerThread::~CTheWorkerThread() { End(INFINITE, false); }
//////////////////////////////////////////////////////////////////////////
//
// Function: StartThread
//
// Synopsis: Start the worker thread on its merry way
//
//////////////////////////////////////////////////////////////////////////
bool CTheWorkerThread::Start( /*[in]*/ DWORD dwWaitInterval, /*[in]*/ Callback* pfnCallback ) { _ASSERT( m_ThreadInfo.hThread == NULL && NULL != pfnCallback );
bool bReturn = false;
if ( NULL == m_ThreadInfo.hThread ) { m_ThreadInfo.pfnCallback = pfnCallback; if ( dwWaitInterval ) { m_ThreadInfo.dwWaitInterval = dwWaitInterval; m_ThreadInfo.bExit = false; } m_ThreadInfo.hWait = CreateEvent(NULL, TRUE, FALSE, NULL); if ( NULL != m_ThreadInfo.hWait ) { m_ThreadInfo.hExit = CreateEvent(NULL, TRUE, FALSE, NULL); if ( NULL != m_ThreadInfo.hExit ) { m_ThreadInfo.hThread = (HANDLE) _beginthreadex( NULL, 0, CTheWorkerThread::ThreadFunc, &m_ThreadInfo, 0, &m_ThreadInfo.dwThreadId ); if ( m_ThreadInfo.hThread ) { bReturn = true; } } } }
return bReturn; }
//////////////////////////////////////////////////////////////////////////
//
// Function: EndThread
//
// Synopsis: Attempt to end the worker thread
//
//////////////////////////////////////////////////////////////////////////
bool CTheWorkerThread::End( /*[in]*/ DWORD dwTimeOut, /*[in]*/ bool bTerminateAfterWait ) { bool bReturn = true;
if ( m_ThreadInfo.hThread ) { bReturn = false;
// Set thread exiting flag to true (see ThreadFunc below...)
m_ThreadInfo.bExit = true;
// Resume our worker (if its currently suspended otherwise no-op)
Resume();
// Wake it up if its idle
SetEvent(m_ThreadInfo.hWait);
// Wait for it to exit
if ( WAIT_OBJECT_0 != WaitForSingleObjectEx(m_ThreadInfo.hExit, dwTimeOut, FALSE) ) { if ( bTerminateAfterWait ) { _endthreadex((unsigned)m_ThreadInfo.hThread);
// OK, we're without a thread now...
CloseHandle(m_ThreadInfo.hWait); CloseHandle(m_ThreadInfo.hExit); CloseHandle(m_ThreadInfo.hThread); m_ThreadInfo.hThread = NULL; bReturn = true; } } else { // OK, we're without a thread now...
CloseHandle(m_ThreadInfo.hWait); CloseHandle(m_ThreadInfo.hExit); CloseHandle(m_ThreadInfo.hThread); m_ThreadInfo.hThread = NULL; bReturn = true; } }
return bReturn; }
//////////////////////////////////////////////////////////////////////////
//
// Function: SuspendThread
//
// Synopsis: Suspend the worker thread
//
//////////////////////////////////////////////////////////////////////////
void CTheWorkerThread::Suspend(void) { _ASSERT(m_ThreadInfo.hThread); m_ThreadInfo.bSuspended = true; ::SuspendThread(m_ThreadInfo.hThread); }
//////////////////////////////////////////////////////////////////////////
//
// Function: ResumeThread
//
// Synopsis: Resume the worker thread
//
//////////////////////////////////////////////////////////////////////////
void CTheWorkerThread::Resume(void) { _ASSERT(m_ThreadInfo.hThread); m_ThreadInfo.bSuspended = false; ::ResumeThread(m_ThreadInfo.hThread); }
//////////////////////////////////////////////////////////////////////////
//
// Function: GetHandle()
//
// Synopsis: Return the thread handle
//
//////////////////////////////////////////////////////////////////////////
HANDLE CTheWorkerThread::GetHandle(void) { return m_ThreadInfo.hThread; }
//////////////////////////////////////////////////////////////////////////
//
// Function: ThreadFunc
//
// Synopsis: The worker thread function
//
//////////////////////////////////////////////////////////////////////////
unsigned _stdcall CTheWorkerThread::ThreadFunc(LPVOID pThreadInfo) { // If One Shot Then
// Do some work
// Else
// While not time to exit
// Do some work
// Go idle for the wait interval
// End While
// End While
// End If
// Set exit event (synchronize thread termination)
SetThreadPriority(((PTHREADINFO)pThreadInfo)->hThread, THREAD_PRIORITY_HIGHEST);
if ( ((PTHREADINFO)pThreadInfo)->bExit ) { ((PTHREADINFO)pThreadInfo)->pfnCallback->DoCallback(); } else { while ( ! ((PTHREADINFO)pThreadInfo)->bExit ) { ((PTHREADINFO)pThreadInfo)->pfnCallback->DoCallback();
WaitForSingleObjectEx( ((PTHREADINFO)pThreadInfo)->hWait, ((PTHREADINFO)pThreadInfo)->dwWaitInterval, FALSE );
} } SetEvent(((PTHREADINFO)pThreadInfo)->hExit);
return 0; }
|