276 lines
6.7 KiB
C++
276 lines
6.7 KiB
C++
/////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// Copyright (c) 1997-1999 Microsoft Corporation
|
|
//
|
|
// Module Name:
|
|
// WorkThrd.h
|
|
//
|
|
// Abstract:
|
|
// Definition of the CWorkerThread class.
|
|
//
|
|
// Implementation File:
|
|
// WorkThrd.cpp
|
|
//
|
|
// Author:
|
|
// David Potter (davidp) November 17, 1997
|
|
//
|
|
// Revision History:
|
|
//
|
|
// Notes:
|
|
//
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
|
|
#ifndef __WORKTHRD_H_
|
|
#define __WORKTHRD_H_
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// Forward Class Declarations
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
|
|
class CWorkerThread;
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// External Class Declarations
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// Include Files
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
|
|
#ifndef _EXCOPER_H_
|
|
#include "ExcOper.h" // for CNTException
|
|
#endif
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// Type Definitions
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
|
|
// Worker thread function codes.
|
|
enum
|
|
{
|
|
WTF_EXIT = -1, // Ask the thread to exit.
|
|
WTF_NONE = 0, // No function.
|
|
WTF_USER = 1000 // User functions start here.
|
|
};
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
//++
|
|
//
|
|
// class CWorkerThread
|
|
//
|
|
// Purpose:
|
|
// This class provides a means of calling functions in a worker thread
|
|
// and allowing a UI application to still respond to Windows messages.
|
|
// The user of this class owns the input and output data pointed to
|
|
// by this class.
|
|
//
|
|
// Inheritance:
|
|
// CWorkerThread
|
|
//
|
|
//--
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
|
|
class CWorkerThread
|
|
{
|
|
public:
|
|
//
|
|
// Construction and destruction.
|
|
//
|
|
|
|
// Default constructor
|
|
CWorkerThread( void )
|
|
: m_hThread( NULL )
|
|
, m_hMutex( NULL )
|
|
, m_hInputEvent( NULL )
|
|
, m_hOutputEvent( NULL)
|
|
, m_idThread( 0 )
|
|
, m_bThreadExiting( FALSE )
|
|
, m_nFunction( WTF_NONE )
|
|
, m_pvParam1( NULL )
|
|
, m_pvParam2( NULL )
|
|
, m_dwOutputStatus( ERROR_SUCCESS )
|
|
, m_nte( ERROR_SUCCESS )
|
|
, m_pfnOldWndProc( NULL )
|
|
, m_hCurrentCursor( NULL )
|
|
{
|
|
} //*** CWorkerThread()
|
|
|
|
// Destructor
|
|
~CWorkerThread( void )
|
|
{
|
|
ATLASSERT( m_nFunction == WTF_NONE );
|
|
ATLASSERT( m_pvParam1 == NULL );
|
|
ATLASSERT( m_pvParam2 == NULL );
|
|
|
|
Cleanup();
|
|
|
|
ATLASSERT( m_bThreadExiting );
|
|
|
|
} //*** ~CWorkerThread()
|
|
|
|
// Create the thread
|
|
DWORD CreateThread( void );
|
|
|
|
// Ask the thread to exit
|
|
void QuitThread( IN HWND hwnd = NULL )
|
|
{
|
|
ATLASSERT( ! m_bThreadExiting );
|
|
CWaitCursor wc;
|
|
CallThreadFunction( hwnd, WTF_EXIT, NULL, NULL );
|
|
|
|
} //*** QuitThread()
|
|
|
|
// Call a function supported by the thread
|
|
DWORD CallThreadFunction(
|
|
IN HWND hwnd,
|
|
IN LONG nFunction,
|
|
IN OUT PVOID pvParam1 = NULL,
|
|
IN OUT PVOID pvParam2 = NULL
|
|
);
|
|
|
|
// Wait for the thread to exit
|
|
DWORD WaitForThreadToExit( IN HWND hwnd );
|
|
|
|
public:
|
|
//
|
|
// Accessor functions.
|
|
//
|
|
|
|
// Get the thread handle
|
|
operator HANDLE( void ) const
|
|
{
|
|
return m_hThread;
|
|
|
|
} //*** operator HANDLE()
|
|
|
|
// Get the thread handle
|
|
HANDLE HThreadHandle( void ) const
|
|
{
|
|
return m_hThread;
|
|
|
|
} //*** HThreadHandle()
|
|
|
|
// Get the thread ID
|
|
operator DWORD( void ) const
|
|
{
|
|
return m_idThread;
|
|
|
|
} //*** operator DWORD()
|
|
|
|
// Get exception information resulting from a thread function call
|
|
CNTException & Nte( void )
|
|
{
|
|
return m_nte;
|
|
|
|
} //*** Nte()
|
|
|
|
// Get exception information resulting from a thread function call
|
|
operator CNTException *( void )
|
|
{
|
|
return &m_nte;
|
|
|
|
} //*** operator CNTException *()
|
|
|
|
protected:
|
|
//
|
|
// Synchronization data.
|
|
//
|
|
HANDLE m_hThread; // Handle for the thread.
|
|
HANDLE m_hMutex; // Handle for the mutex used to call a
|
|
// function in the thread.
|
|
HANDLE m_hInputEvent; // Handle for the event used by the calling
|
|
// thread to signal the worker thread that
|
|
// there is work to do.
|
|
HANDLE m_hOutputEvent; // Handle for the event used by the worker
|
|
// thread to signal the calling thread
|
|
// that the work has been completed.
|
|
UINT m_idThread; // ID for the thread.
|
|
BOOL m_bThreadExiting; // Determine if thread is exiting or not.
|
|
|
|
//
|
|
// Data used as input or produced by the thread.
|
|
//
|
|
LONG m_nFunction; // ID of the function to perform.
|
|
PVOID m_pvParam1; // Parameter 1 with function-specific data.
|
|
PVOID m_pvParam2; // Parameter 2 with function-specific data.
|
|
DWORD m_dwOutputStatus; // Status returned from the function.
|
|
CNTException m_nte; // Exception information from the function.
|
|
|
|
//
|
|
// Data and methods for handling WM_SETCURSOR messages.
|
|
//
|
|
WNDPROC m_pfnOldWndProc; // Old window procedure for the parent window.
|
|
HCURSOR m_hCurrentCursor; // Cursor to display while waiting for thread call to complete.
|
|
|
|
// Window procedure for subclassing the parent window
|
|
static LRESULT WINAPI S_ParentWndProc(
|
|
IN HWND hwnd,
|
|
IN UINT uMsg,
|
|
IN WPARAM wParam,
|
|
IN LPARAM lParam
|
|
);
|
|
|
|
//
|
|
// Thread worker functions.
|
|
//
|
|
|
|
// Static thread procedure
|
|
static UINT __stdcall S_ThreadProc( IN OUT LPVOID pvThis );
|
|
|
|
// Thread function handler
|
|
virtual DWORD ThreadFunctionHandler(
|
|
IN LONG nFunction,
|
|
IN OUT PVOID pvParam1,
|
|
IN OUT PVOID pvParam2
|
|
) = 0;
|
|
|
|
//
|
|
// Helper functions.
|
|
//
|
|
|
|
// Prepare a window to wait for a thread operation
|
|
void PrepareWindowToWait( IN HWND hwnd );
|
|
|
|
// Cleanup a window after waiting for a thread operation
|
|
void CleanupWindowAfterWait( IN HWND hwnd );
|
|
|
|
// Cleanup objects
|
|
virtual void Cleanup( void )
|
|
{
|
|
if ( m_hThread != NULL )
|
|
{
|
|
if ( ! m_bThreadExiting && (m_nFunction != WTF_EXIT) )
|
|
{
|
|
QuitThread();
|
|
} // if: thread hasn't exited yet
|
|
ATLTRACE( _T("CWorkerThread::Cleanup() - Closing thread handle\n") );
|
|
CloseHandle( m_hThread );
|
|
m_hThread = NULL;
|
|
} // if: thread created
|
|
if ( m_hMutex != NULL )
|
|
{
|
|
ATLTRACE( _T("CWorkerThread::Cleanup() - Closing mutex handle\n") );
|
|
CloseHandle( m_hMutex );
|
|
m_hMutex = NULL;
|
|
} // if: mutex created
|
|
if ( m_hInputEvent != NULL )
|
|
{
|
|
ATLTRACE( _T("CWorkerThread::Cleanup() - Closing input event handle\n") );
|
|
CloseHandle( m_hInputEvent );
|
|
m_hInputEvent = NULL;
|
|
} // if: input event created
|
|
if ( m_hOutputEvent != NULL )
|
|
{
|
|
ATLTRACE( _T("CWorkerThread::Cleanup() - Closing output event handle\n") );
|
|
CloseHandle( m_hOutputEvent );
|
|
m_hOutputEvent = NULL;
|
|
} // if: output event created
|
|
|
|
} //*** Cleanup()
|
|
|
|
}; // class CWorkerThread
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
|
|
#endif // __WORKTHRD_H_
|