240 lines
5.8 KiB
C++
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() );
|
||
|
}
|
||
|
}
|
||
|
|