|
// Thread.cpp: implementation of the CThread class, revision 2
//
// Copyright (C) 2002 First Objective Software, Inc. All rights reserved
// Go to www.firstobject.com for the latest version and information
// Retain this disclaimer: This software class is provided as is. No warranty
// You may use this class even in commercial applications, enjoy!
#include "stdafx.h"
#include "Thread.h"
#include <process.h>
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif
//
// CThread
//
// The parent thread is the one that instantiated the CThread object
// The child thread only exists between Start() and Stop()
// Start() and Stop() are called by the parent thread
// The others are all subroutines of the child thread's StartAddress() function
//
// A CEvent is used to synchronize the threads via two simple methods
// CEvent::Lock() is used by one thread to wait on an event
// CEvent::SetEvent() is used by the other thread to signal (i.e. trigger) the event
//
/////////////////////////////////////////////////////////////////////////////
// Parent thread functions
BOOL CThread::Start()
{
// Start the thread if it hasn't already been started
if ( ! m_hThread )
{
// Reset cleanup event in case previous thread ended on its own
m_eventWaitForCleanup.ResetEvent();
// Start child thread and specify controlling function
/*
CWinThread* pThread = AfxBeginThread( StartAddress, this );
m_dwThreadID = pThread->m_nThreadID;
m_hThread = pThread->m_hThread;
*/
m_hThread = (HANDLE)_beginthreadex(
NULL, // LPSECURITY_ATTRIBUTES
NULL, // unsigned stack size
StartAddress, // function pointer
this, // CThread object pointer
1, // initflag
(unsigned*)&m_dwThreadID // identifier
);
}
return ( m_hThread != 0 );
}
void CThread::Stop( BOOL bBlock )
{
// Signal exit event and wait for Run() to complete
// Note that the thread may have already stopped on its own (or never started)
if ( m_hThread )
{
m_eventExit.SetEvent();
if ( bBlock )
{
// The parent thread blocks for cleanup
m_eventWaitForCleanup.Lock();
}
}
}
/////////////////////////////////////////////////////////////////////////////
// Child thread functions
unsigned int __stdcall CThread::StartAddress(void* pv)
{
// This is the control function for the child thread
CThread* pMT = (CThread*)pv;
CoInitialize( NULL );
int nReturnCode = pMT->Main();
CoUninitialize();
pMT->Release();
return nReturnCode;
}
UINT CThread::Main()
{
// Copy and override this function in derived class
// Do setup and notify service of m_eventService if necessary
// Loop: Wait() returns after service event, timeout, or exit
// You can do simple polling by just specifying wait in millisends
while ( Wait() )
{
// Perform service event handling
}
// Do cleanup
// DEADLOCK WARNING:
// If the parent process is waiting for cleanup (Stop(TRUE)),
// do not do anything to cause SendMessage() to parent process
// such as SetWindowText because that calls its WinProc directly.
return 0;
}
BOOL CThread::WaitOnHandle( HANDLE hObject, DWORD dwMilliSecs )
{
// This waits on both the specified event and the exit event, or timeout
// Result of CMultiLock::Lock() is stored in m_dwWaitResult;
// Returns TRUE if specified event or timeout was triggered, otherwise FALSE
HANDLE aHandles[2];
aHandles[0] = hObject;
aHandles[1] = (HANDLE)m_eventExit;
// Wait on either of the two objects
m_dwWaitResult = WaitForMultipleObjects( 2, aHandles, FALSE, dwMilliSecs );
// Return TRUE if service event or timeout
if ( m_dwWaitResult == WAIT_OBJECT_0 // service event
|| m_dwWaitResult == WAIT_TIMEOUT )
return TRUE;
return FALSE;
}
BOOL CThread::Wait( DWORD dwMilliSecs )
{
return WaitOnHandle( (HANDLE)m_eventService, dwMilliSecs );
}
void CThread::Release()
{
// Release m_eventWaitForCleanup after Run()
CloseHandle(m_hThread);
m_hThread = NULL;
m_eventWaitForCleanup.SetEvent();
}
|
By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.
If a file you wish to view isn't highlighted, and is a text file (not binary), please
let us know and we'll add colourisation support for it.
Raised in Southern Ontario Canada. Bachelor of Science from the University of Toronto in Computer Science and Anthropology. Living near Washington D.C. in Virginia, USA.