Game Accessibility Library logo SourceForge.net Logo
Game Accessibility Suite: CAT/CATThread.cpp Source File

CATThread.cpp

Go to the documentation of this file.
00001 //---------------------------------------------------------------------------
00002 /// \file    CATThread.cpp
00003 /// \brief   Base Thread Class
00004 /// \ingroup CAT
00005 ///
00006 /// Copyright (c) 2003-2008 by Michael Ellison.
00007 /// See COPYING.txt for the \ref gaslicense License (MIT License).
00008 ///
00009 // $Author: mikeellison $
00010 // $Date: 2008-01-23 08:59:02 -0600 (Wed, 23 Jan 2008) $
00011 // $Revision:   $
00012 // $NoKeywords: $
00013 //---------------------------------------------------------------------------
00014 
00015 #include "CATThread.h"
00016 
00017 // Thread construction
00018 CATThread::CATThread()
00019 {
00020     this->fThreadHandle = 0;
00021     this->fUserParam    = 0;
00022     this->fCallback     = 0;
00023 }
00024 
00025 // Thread destruction
00026 CATThread::~CATThread()
00027 {
00028     if (this->fThreadHandle != 0)
00029     {
00030         if (!this->WaitStop(1000))
00031         {
00032             CATTRACE("Warning: Forcing thread to stop...");
00033             this->ForceStop();
00034         }
00035     }
00036 }
00037 
00038 
00039 // Start a thread. This is the one used if you're deriving from
00040 // CATThread for your own threaded class.  Override ThreadFunction()
00041 // for your subclass...
00042 bool CATThread::Start(void *param)
00043 {
00044     CATASSERT(fThreadHandle == 0, "Starting a thread that's already running. Bad form....");
00045     if (fThreadHandle != 0)
00046     {
00047         return false;
00048     }
00049 
00050     this->fCallback  = 0;
00051     this->fUserParam = param;
00052 
00053 
00054     fThreadHandle = (HANDLE)_beginthreadex(0,0,W32ThreadProc,this,0,&fThreadId);
00055 
00056     // If startup was successful, return true
00057     if (fThreadHandle != INVALID_HANDLE_VALUE)
00058     {
00059         return true;
00060     }
00061 
00062     // Thread couldn't start - bail.
00063     fThreadHandle = 0;
00064     return false;
00065 }
00066 
00067 // Start a thread procedure.  You can use this directly w/o deriving
00068 // just by creating your procedure from the CATTHREADPROC prototype.
00069 bool CATThread::StartProc(CATTHREADPROC proc, void* param)
00070 {
00071     CATASSERT(fThreadHandle == 0, "Starting a thread that's already running. Bad form...");
00072     if (fThreadHandle != 0)
00073     {
00074         return false;
00075     }
00076 
00077     this->fCallback = proc;
00078     this->fUserParam = param;
00079 
00080     unsigned int threadId;
00081     fThreadHandle = (HANDLE)_beginthreadex(0,0,W32ThreadProc,this,0,&threadId);
00082     if (fThreadHandle != INVALID_HANDLE_VALUE)
00083     {
00084         return true;
00085     }
00086 
00087     fThreadHandle = 0;
00088     return false;
00089 }
00090 
00091 // Wait until the thread stops or the timer times out.
00092 // If successful, clears the thread handle. Start or StartProc must
00093 // be called before other thread commands are used.
00094 bool CATThread::WaitStop(CATUInt32 timeout, CATUInt32* exitCode )
00095 {
00096     if (fThreadHandle == 0)
00097     {
00098         return true;
00099     }
00100 
00101     if (timeout == -1)
00102     {
00103         timeout = INFINITE;
00104     }
00105 
00106     if (WAIT_TIMEOUT == WaitForSingleObject(fThreadHandle,timeout))
00107     {
00108         return false;
00109     }
00110 
00111     if (exitCode)
00112     {   
00113         GetExitCodeThread(fThreadHandle,(DWORD*)exitCode);
00114     }
00115     
00116     CloseHandle(fThreadHandle);
00117 
00118     fThreadHandle   = 0;
00119     fCallback       = 0;
00120     fUserParam      = 0;
00121     return true;
00122 }
00123 
00124 // Forces a thread to stop - use sparingly.  As WaitStop does, this
00125 // one clears the thread handle.  Start or StartProc must be called
00126 // prior to calling other commands after ForceStop is issued.
00127 void CATThread::ForceStop()
00128 {
00129     if (fThreadHandle == 0)
00130     {
00131         return;
00132     }
00133 
00134     TerminateThread(fThreadHandle,-1);
00135     CloseHandle(fThreadHandle);
00136     fThreadHandle = 0;
00137     fCallback = 0;
00138     fUserParam = 0;
00139 }
00140 
00141 // Pause the thread. Thread must have been started before use.
00142 bool CATThread::Pause()
00143 {
00144     CATASSERT(fThreadHandle != 0, "Invalid thread handle in Pause - start it first!");
00145 
00146     if (fThreadHandle == 0)
00147     {
00148         return false;
00149     }
00150 
00151     return (SuspendThread(fThreadHandle) >= 0);
00152 }
00153 
00154 // Resume the thread. Thread must have been started before use.
00155 bool CATThread::Resume()
00156 {
00157     CATASSERT(fThreadHandle != 0, "Invalid thread handle in Resume - start it first!");
00158 
00159     if (fThreadHandle == 0)
00160     {
00161         return false;
00162     }
00163 
00164     return (ResumeThread(fThreadHandle) >= 0);
00165 }
00166 
00167 // Thread function - either override this if you are deriving
00168 // from the class, or leave as is and it will call the CATTHREADPROC
00169 // procedure from a StartProc, then exit.
00170 void CATThread::ThreadFunction()
00171 {
00172     if (this->fCallback)
00173     {
00174         fCallback(this->fUserParam,this);
00175     }
00176 }
00177 
00178 
00179 // OS specific thread - note, the param is NOT the user param, 
00180 // rather it is a pointer to the thread object....
00181 unsigned int _stdcall CATThread::W32ThreadProc(void *param)
00182 {
00183     CATThread* theThread = (CATThread*)param;
00184     theThread->ThreadFunction();
00185     return 0;
00186 }

Generated on Mon Feb 11 04:09:49 2008 for Game Accessibility Suite by doxygen 1.5.4