#ifndef __TCThread_h__ #define __TCThread_h__ #include "AutoHandle.h" ///////////////////////////////////////////////////////////////////////////// // TCThread.h | Declaration of the TCThread class // ///////////////////////////////////////////////////////////////////////////// // Forward Declarations ///////////////////////////////////////////////////////////////////////////// // Type definition/prototype for a user-defined callback function that // represents a thread, specified as the /pfnThreadProc/ parameters of the // TCThread::BeginThread method. // // See Also: TCThread, TCThread::BeginThread typedef unsigned (__stdcall* TC_THREADPROC)(void*); ///////////////////////////////////////////////////////////////////////////// // Remarks: This class is like CWinThread with all that Thread State and // m_pMainWnd stuff removed from it. It came about because many COM objects // won't be able to use CWinThread because there won't be a MainWnd for the // thread to be associated with. This class does not use MFC. // // The Usage is almost identical to CWinThread. Call the static function // TCThread::BeginThread() to create and start the thread. When the // controlling function returns, the thread is automatically cleaned up, just // like CWinThread. The following function may also be used on the thread: // // int GetThreadPriority() // BOOL SetThreadPriority(int nPriority) // DWORD SuspendThread() // DWORD ResumeThread() // bool PostThreadMessage(UINT message, WPARAM wParam, LPARAM lParam) class TCThread { // Construction / Destruction public: TCThread(); TCThread(TC_THREADPROC pfnThreadProc, LPVOID pParam); virtual ~TCThread(); // Static functions to create and return a TCThread static TCThread* BeginThread(TC_THREADPROC pfnThreadProc, LPVOID pParam, int nPriority = THREAD_PRIORITY_NORMAL, UINT nStackSize = 0, DWORD dwCreateFlags = 0, LPSECURITY_ATTRIBUTES pSecurityAttrs = NULL); static TCThread* BeginMsgThread(TC_THREADPROC pfnThreadProc, LPVOID pParam, int nPriority = THREAD_PRIORITY_NORMAL, UINT nStackSize = 0, DWORD dwCreateFlags = 0, LPSECURITY_ATTRIBUTES pSecurityAttrs = NULL); // Called by TCBeginThread bool CreateThread(bool bMsgQueue = false, DWORD dwCreateFlags = 0, UINT nStackSize = 0, LPSECURITY_ATTRIBUTES pSecurityAttrs = NULL); void EndThread(UINT nExitCode, bool bDelete = true); // 'delete this' only if m_bAutoDelete == true void Delete(); // Group=Attributes public: HANDLE m_hThread; // This thread's HANDLE DWORD m_nThreadID; // This thread's ID bool m_bAutoDelete:1; // Enables 'delete this' after thread termination TCHandle m_hEventExit; // Thread proc can wait for this int GetThreadPriority(); bool SetThreadPriority(int nPriority); // Operations public: DWORD SuspendThread(); DWORD ResumeThread(); bool PostThreadMessage(UINT message, WPARAM wParam = 0, LPARAM lParam = 0); DWORD SignalExitAndWait(DWORD dwWait = INFINITE); // Operators public: operator HANDLE() const; // Implementation public: // These items aren't for user consumption. void CommonConstruct(); // Actual entry point for all threads of this type. static UINT __stdcall TCThreadEntry(void* pParam); static UINT __stdcall TCMsgThreadEntry(void* pParam); // Group=Data Members public: // Parameters passed to starting function. Used internally. LPVOID m_pThreadParams; TC_THREADPROC m_pfnThreadProc; DWORD m_dwCreateFlags; // Events to coordinate thread startup. Used internally. TCHandle m_hEvent, m_hEvent2; // Error checking. Used internally. bool m_bError:1, m_bMsgQueue:1; }; ///////////////////////////////////////////////////////////////////////////// // Group=Attributes ///////////////////////////////////////////////////////////////////////////// // Description: Gets the priority of the current thread. // // Return Value: The current thread priority level within its priority class. // The value returned will be one of the following, listed from highest // priority to lowest: // // + THREAD_PRIORITY_TIME_CRITICAL // + THREAD_PRIORITY_HIGHEST // + THREAD_PRIORITY_ABOVE_NORMAL // + THREAD_PRIORITY_NORMAL // + THREAD_PRIORITY_BELOW_NORMAL // + THREAD_PRIORITY_LOWEST // + THREAD_PRIORITY_IDLE // // Sets the priority of the current thread. // // See Also: TCThread::SetThreadPriority inline int TCThread::GetThreadPriority() { assert(NULL != m_hThread); return ::GetThreadPriority(m_hThread); } ///////////////////////////////////////////////////////////////////////////// // Description: Sets the priority of the current thread. // // Return Value: Nonzero if function was successful; otherwise 0. // // Parameters: // nPriority - Specifies the new thread priority level within its priority // class. This parameter must be one of the following values, listed from // highest priority to lowest: // // THREAD_PRIORITY_TIME_CRITICAL // // THREAD_PRIORITY_HIGHEST // // THREAD_PRIORITY_ABOVE_NORMAL // // THREAD_PRIORITY_NORMAL // // THREAD_PRIORITY_BELOW_NORMAL // // THREAD_PRIORITY_LOWEST // // THREAD_PRIORITY_IDLE // // This function sets the priority level of the current thread within its // priority class. It can only be called after CreateThread successfully // returns. // // See Also: TCThread::GetThreadPriority inline bool TCThread::SetThreadPriority(int nPriority) { assert(NULL != m_hThread); return !!::SetThreadPriority(m_hThread, nPriority); } ///////////////////////////////////////////////////////////////////////////// // Group=Operations ///////////////////////////////////////////////////////////////////////////// // Description: Increments a thread's suspend count. // // Increments the current thread's suspend count. If any thread has a suspend // count above zero, that thread does not execute. The thread can be resumed // by calling the ResumeThread member function. // // Return Value: The thread's previous suspend count if successful; // 0xFFFFFFFF otherwise. // // See Also: TCThread::ResumeThread inline DWORD TCThread::SuspendThread() { assert(NULL != m_hThread); return ::SuspendThread(m_hThread); } ///////////////////////////////////////////////////////////////////////////// // Description: Decrements a thread's suspend count. // // Called to resume execution of a thread that was suspended by the // SuspendThread member function, or a thread created with the // CREATE_SUSPENDED flag. The suspend count of the current thread is reduced // by one. If the suspend count is reduced to zero, the thread resumes // execution; otherwise the thread remains suspended. // // Return Value: The thread's previous suspend count if successful; // 0xFFFFFFFF otherwise. If the return value is zero, the current thread was // not suspended. If the return value is one, the thread was suspended, but // is now restarted. Any return value greater than one means the thread // remains suspended. inline DWORD TCThread::ResumeThread() { assert(NULL != m_hThread); return ::ResumeThread(m_hThread); } ///////////////////////////////////////////////////////////////////////////// // Description: Posts a message to the message queue of this thread. // // Return Value: Nonzero if successful; otherwise 0. // // Parameters: // message - ID of the user-defined message. // wParam - First message parameter. // lParam - Second message parameter. // // Called to post a message to the message queue of this object. inline bool TCThread::PostThreadMessage(UINT message, WPARAM wParam, LPARAM lParam) { assert(NULL != m_hThread); assert(0 != m_nThreadID); return !!::PostThreadMessage(m_nThreadID, message, wParam, lParam); } inline DWORD TCThread::SignalExitAndWait(DWORD dwWait) { HANDLE hth = m_hThread; ::SetEvent(m_hEventExit); if (m_bMsgQueue) PostThreadMessage(WM_QUIT, 0, 0); return WaitForSingleObject(hth, dwWait); } ///////////////////////////////////////////////////////////////////////////// // Group=Operators inline TCThread::operator HANDLE() const { return (NULL == this) ? NULL : m_hThread; } ///////////////////////////////////////////////////////////////////////////// #endif // __TCThread_h__