windows-nt/Source/XPSP1/NT/inetsrv/query/h/thrd32.hxx
2020-09-26 16:20:57 +08:00

240 lines
5.8 KiB
C++

//+---------------------------------------------------------------------------
//
// Microsoft Windows
// Copyright (c) Microsoft Corporation, 1992-1999
//
// File: THRD32.HXX
//
// Contents: Windows thread abstraction
//
// Classes: CThread
//
// History: 27-Feb-92 BartoszM Created
//
// Notes: Thread object
//----------------------------------------------------------------------------
#pragma once
//+---------------------------------------------------------------------------
//
// Class: CThread
//
// Purpose: Encapsulation of thread
//
// History: 27-Feb-92 BartoszM Created
//
//----------------------------------------------------------------------------
class CThread
{
public:
inline CThread ( LPTHREAD_START_ROUTINE pFun,
void* pData,
BOOL fSuspend=FALSE );
inline ~CThread ();
inline void SetPriority( int nPriority );
inline DWORD Suspend();
inline DWORD Resume ();
inline BOOL IsRunning() { return !_fSuspended; }
inline void WaitForDeath(DWORD dwMilliseconds = 0xFFFFFFFF);
const HANDLE GetHandle() const { return _handle; }
DWORD GetThreadId() const { return _tid; }
private:
static DWORD _ThreadFunction( void * pv )
{
DWORD dw = 0;
//
// Don't display system errors in worker threads -- the
// service needs to keep running always.
//
CNoErrorMode noErrors;
CTranslateSystemExceptions translate;
TRY
{
CThread & me = * (CThread *) pv;
dw = me._pFun( me._pData );
}
CATCH( CException, e )
{
//
// We should never get here, since each thread is responsible
// for dealing with exceptions and leaving cleanly.
//
Win4Assert( !"CThread top-level exception not handled properly" );
}
END_CATCH
return dw;
}
HANDLE _handle;
DWORD _tid;
LPTHREAD_START_ROUTINE _pFun;
void * _pData;
BOOL _fSuspended;
#if CIDBG == 1
BOOL _fNeverRan;
#endif
};
//+---------------------------------------------------------------------------
//
// Member: CThread::CThread
//
// Synopsis: Creates a new thread
//
// Arguments: [pFun] -- entry point
// [obj] -- pointer passed to thread
// [fSuspend] -- start suspended
//
// History: 27-Feb-92 BartoszM Created
//
//----------------------------------------------------------------------------
inline CThread::CThread( LPTHREAD_START_ROUTINE pFun,
void * obj,
BOOL fSuspend )
: _pFun( pFun ),
_pData( obj ),
_fSuspended( fSuspend )
{
#if CIDBG == 1
_fNeverRan = fSuspend;
#endif
// Start with 16k commit for the stack to make sure we don't run out.
_handle = CreateThread( 0,
4096 * 4,
_ThreadFunction,
(void *) this,
fSuspend ? CREATE_SUSPENDED: 0,
&_tid);
if ( 0 == _handle )
{
THROW( CException() );
}
}
//+---------------------------------------------------------------------------
//
// Member: CThread::~CThread
//
// Synopsis: Closes the handle
//
// History: 10-Nov-92 BartoszM Created
//
//----------------------------------------------------------------------------
inline CThread::~CThread ()
{
Win4Assert( !_fSuspended || _fNeverRan );
if ( !_fSuspended )
WaitForDeath();
CloseHandle( _handle );
}
//+---------------------------------------------------------------------------
//
// Member: CThread::SetPriority
//
// Arguments: [nPriority] -- desired priority
//
// History: 27-Feb-92 BartoszM Created
//
//----------------------------------------------------------------------------
inline void CThread::SetPriority ( int nPriority )
{
if ( !SetThreadPriority ( _handle, nPriority ))
THROW( CException() );
}
//+---------------------------------------------------------------------------
//
// Member: CThread::Suspend
//
// Synopsis: Increments suspension count. Suspends the thread.
//
// Returns: suspended count
//
// History: 27-Feb-92 BartoszM Created
//
//----------------------------------------------------------------------------
inline DWORD CThread::Suspend()
{
DWORD susCount = SuspendThread ( _handle );
if ( 0xffffffff == susCount )
THROW( CException() );
return susCount;
}
//+---------------------------------------------------------------------------
//
// Member: CThread::Resume
//
// Synopsis: Decrements suspension count. Restarts if zero
//
// Returns: suspended count
//
// History: 27-Feb-92 BartoszM Created
//
//----------------------------------------------------------------------------
inline DWORD CThread::Resume()
{
#if CIDBG == 1
_fNeverRan = FALSE;
#endif
DWORD susCount = ResumeThread ( _handle );
if ( 0xffffffff == susCount )
THROW( CException() );
_fSuspended = FALSE;
return susCount;
}
//+---------------------------------------------------------------------------
//
// Member: CThread::WaitForDeath
//
// Synopsis: Block until thread dies.
//
// History: 24-Apr-92 KyleP Created
//
//----------------------------------------------------------------------------
inline void CThread::WaitForDeath( DWORD msec )
{
if ( !_fSuspended )
{
DWORD res = WaitForSingleObject( _handle, msec );
if ( WAIT_FAILED == res )
THROW( CException() );
}
}