|
//====================================================================
// Although great care has gone into developing this software,
// it is provided without any guarantee of reliability, accuracy
// of information, or correctness of operation. I am not responsible
// for any damages that may occur as a result of using this software.
// Use this software entirely at your own risk.
// Copyright 2003, Chris Richardson
//
// Description: Include finder thread, and some helper classes.
//
//====================================================================
#include "stdafx.h"
#include "IncludeFinder.h"
#include "Parser.h"
#include "FileIterator.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
//////////////////////////////////////////////////////////////////////
// CIncludeFinder Implementation.
//////////////////////////////////////////////////////////////////////
CIncludeFinder::CIncludeFinder() :
c_ulThreadID( (unsigned long)-1 ),
c_hThread( INVALID_HANDLE_VALUE ),
c_hStopEvent( INVALID_HANDLE_VALUE ),
c_poInfo( NULL )
{
}
//
// ------------------------------------------------------------------
//
CIncludeFinder::~CIncludeFinder()
{
if( c_hThread != INVALID_HANDLE_VALUE )
{
// We never got stopped.
CloseHandle( c_hThread );
c_hThread = INVALID_HANDLE_VALUE;
}
if( c_hStopEvent != INVALID_HANDLE_VALUE )
{
// Close the event handle.
CloseHandle( c_hStopEvent );
c_hStopEvent = INVALID_HANDLE_VALUE;
}
c_poInfo = NULL;
c_ulThreadID = (unsigned long)-1;
}
//
// ------------------------------------------------------------------
//
unsigned long CIncludeFinder::ThreadProcedure( void * p_pvParam )
{
CIncludeFinder * a_poThread = (CIncludeFinder*)p_pvParam;
return a_poThread->ThreadLoop();
}
//
// ------------------------------------------------------------------
//
unsigned long CIncludeFinder::ThreadLoop()
{
c_poInfo->c_oStartTime = COleDateTime::GetCurrentTime();
c_poInfo->c_ulFilesProcessed = 0;
CParser a_oParser( c_poInfo );
c_poInfo->c_poFileIterator->Prepare( c_hStopEvent, &a_oParser );
BOOL a_bStop = FALSE;
if( !IsTimeToStop() )
{
CTCharString a_sFilePath;
CFileIterator * a_poIterator = c_poInfo->c_poFileIterator;
while( 1 )
{
if( IsTimeToStop() )
{
a_bStop = TRUE;
break;
}
if( !a_poIterator->GetNextFile( a_sFilePath ) )
// We're done.
break;
// Parse the file.
a_oParser.Parse( a_sFilePath.c_str(), &c_poInfo->c_oResults, c_hStopEvent );
// Notify that we are done parsing the file, and give the results.
CParsedFile * a_poFile = a_oParser.GetLastFile();
if( a_poFile )
c_poInfo->c_poStatusNotifier->OnFileComplete( a_poFile );
}
}
c_poInfo->c_oStopTime = COleDateTime::GetCurrentTime();
// Notify that we are finished.
c_poInfo->c_poStatusNotifier->OnFinished();
if( !a_bStop )
{
CloseHandle( c_hThread );
c_hThread = INVALID_HANDLE_VALUE;
}
return 0;
}
//
// ------------------------------------------------------------------
//
BOOL CIncludeFinder::IsRunning()
{
if( c_hThread == INVALID_HANDLE_VALUE )
return FALSE;
return TRUE;
}
//
// ------------------------------------------------------------------
//
unsigned long CIncludeFinder::Stop( unsigned long p_ulTimeout )
{
if( c_hThread == INVALID_HANDLE_VALUE )
{
// We aren't even running.
return -1;
}
// Signal that we want the thread to stop.
SetEvent( c_hStopEvent );
// Wait for the thread to stop, for the specified timeout interval.
unsigned long a_ulResult = WaitForSingleObject( c_hThread, p_ulTimeout );
if( a_ulResult == WAIT_TIMEOUT )
{
// It didn't stop in time. I know termination is bad, so hopefully we won't have to hit this case.
TerminateThread( c_hThread, -2 );
CloseHandle( c_hThread );
c_hThread = INVALID_HANDLE_VALUE;
return 0;
}
CloseHandle( c_hThread );
c_hThread = INVALID_HANDLE_VALUE;
return 0;
}
//
// ------------------------------------------------------------------
//
BOOL CIncludeFinder::IsTimeToStop( unsigned long p_ulTimeout )
{
if( c_hStopEvent == INVALID_HANDLE_VALUE )
{
// We don't want to call WaitForSingleObject on an invalid event.
return TRUE;
}
unsigned long a_ulResult = WaitForSingleObject( c_hStopEvent, p_ulTimeout );
// If we timed out of the WaitForSingleObject, we aren't ready to stop yet.
if( a_ulResult == WAIT_TIMEOUT )
return FALSE;
// Otherwise we are ready to stop, let's do it.
return TRUE;
}
//
// ------------------------------------------------------------------
//
unsigned long CIncludeFinder::Start( unsigned long p_ulStackSize )
{
if( c_hThread != INVALID_HANDLE_VALUE )
{
// Our thread is already created?
return ERROR_ALREADY_EXISTS;
}
// Let's create the event first.
c_hStopEvent = CreateEvent( NULL,
TRUE,
TRUE,
NULL );
if( !c_hStopEvent )
{
// I don't think I've ever seen this case, but it doesn't look good.
return GetLastError();
}
// Reset the event to signal that we are not ready to stop.
ResetEvent( c_hStopEvent );
// Create our thread.
c_hThread = CreateThread( NULL,
p_ulStackSize,
ThreadProcedure,
this,
0,
&c_ulThreadID );
if( !c_hThread )
{
// This is going to be a problem.
return GetLastError();
}
return 0;
}
//
// ------------------------------------------------------------------
//
//////////////////////////////////////////////////////////////////////
// CIncludeFinderInfo Implementation.
//////////////////////////////////////////////////////////////////////
CIncludeFinderInfo::CIncludeFinderInfo() :
c_poStatusNotifier( NULL ),
c_poFileIterator( NULL ),
c_bPreprocess( FALSE )
{
}
//
// ------------------------------------------------------------------
//
CIncludeFinderInfo::~CIncludeFinderInfo()
{
}
//
// ------------------------------------------------------------------
//
void CIncludeFinderInfo::SetOptions( CFileIterator * p_poFileIterator,
BOOL p_bPreprocess )
{
// Must be set somewhere before this is called.
ASSERT( c_poStatusNotifier );
// Can't pass in a bogus iterator.
ASSERT( p_poFileIterator );
c_poFileIterator = p_poFileIterator;
c_bPreprocess = p_bPreprocess;
c_ulFilesProcessed = 0;
}
//
// ------------------------------------------------------------------
//
|
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.