00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 
00012 
00013 
00014 
00015 
00016 
00017 
00018 
00019 
00020 
00021 
00022 
00023 
00024 
00025 
00026 
00027 
00028 
00029 
00030 
00031 
00032 
00033 
00034 
00035 
00036 #include "stdafx.h"
00037 #include "Win32Thread.h"
00038 
00039 #include "ErrorHandlerMacros.h"
00040 
00041 #ifdef _MEMORY_DEBUG 
00042     #define new    DEBUG_NEW  
00043     #define malloc DEBUG_MALLOC  
00044     static char THIS_FILE[] = __FILE__;  
00045 #endif
00046 
00047 KOMODIA_NAMESPACE_START
00048 
00049 #define CWin32Thread_Class "CWin32Thread"
00050 
00051 CWin32Thread::CWin32Thread(LPGenericThreadProc pThreadProc) : CGenericThread(pThreadProc),
00052                                                               m_hThread(0)
00053 {
00054     try
00055     {
00056         
00057         SetName(CWin32Thread_Class);
00058 
00059         
00060         if (GetThreadProc())
00061         {
00062             
00063             DWORD dwThreadID;
00064 
00065             
00066             m_hThread=CreateThread(NULL,
00067                                    0,
00068                                    Win32Thread,
00069                                    this,
00070                                    CREATE_SUSPENDED,
00071                                    &dwThreadID);
00072 
00073             
00074             if (m_hThread)
00075             {
00076                 
00077                 SetThreadID(dwThreadID);
00078 
00079                 
00080                 SetThreadStatus(tsSuspended);
00081             }
00082             else
00083                 
00084                 throw std::string("Failed to create thread!");
00085         }
00086         else
00087             
00088             throw std::string("No thread proc!");
00089     }
00090     ERROR_HANDLER_RETHROW("CWin32Thread")
00091 }
00092 
00093 CWin32Thread::~CWin32Thread()
00094 {
00095     try
00096     {
00097         
00098         Stop();
00099     }
00100     ERROR_HANDLER("~CWin32Thread")
00101 }
00102 
00103 BOOL CWin32Thread::Start(LPVOID pData)
00104 {
00105     try
00106     {
00107         if (GetThreadStatus()==tsStopped)
00108         {
00109             
00110             
00111             DWORD dwThreadID;
00112 
00113             
00114             m_hThread=CreateThread(NULL,
00115                                    0,
00116                                    Win32Thread,
00117                                    this,
00118                                    CREATE_SUSPENDED,
00119                                    &dwThreadID);
00120 
00121             
00122             if (m_hThread)
00123             {
00124                 
00125                 SetThreadID(dwThreadID);
00126 
00127                 
00128                 SetThreadStatus(tsSuspended);
00129             }
00130             else
00131                 
00132                 return FALSE;
00133         }
00134         else if (GetThreadStatus()!=tsSuspended)
00135             return FALSE;
00136 
00137         
00138         CGenericThread::Start(pData);
00139 
00140         
00141         if (m_hThread)
00142             if (ResumeThread(m_hThread)!=-1)
00143                 
00144                 return TRUE;
00145 
00146         return FALSE;
00147     }
00148     ERROR_HANDLER_RETURN("Start",FALSE)
00149 }
00150 
00151 BOOL CWin32Thread::Stop()
00152 {
00153     try
00154     {
00155         
00156         
00157         if (m_hThread)
00158         {
00159             
00160             if (GetThreadStatus()==tsRunning &&
00161                 GetBruteTermination())
00162                 
00163                 if (!TerminateThread(m_hThread,THREAD_DO_NOTHING_EXIT_VALUE))
00164                     return FALSE;
00165 
00166             if (GetThreadStatus()==tsSuspended ||
00167                 GetThreadStatus()==tsRunning)
00168                 if (CloseHandle(m_hThread))
00169                 {
00170                     
00171                     m_hThread=NULL;
00172 
00173                     
00174                     SetThreadStatus(tsStopped);
00175 
00176                     
00177                     return TRUE;
00178                 }
00179                 else
00180                     return FALSE;
00181             else
00182             {
00183                 
00184                 if (!CloseHandle(m_hThread))
00185                     m_hThread=NULL;
00186 
00187                 
00188                 return FALSE;
00189             }
00190         }
00191         else
00192             return FALSE;
00193     }
00194     ERROR_HANDLER_RETURN("Stop",FALSE)
00195 }
00196 
00197 DWORD WINAPI CWin32Thread::Win32Thread(LPVOID lpData)
00198 {
00199     try
00200     {
00201         
00202         CWin32Thread* pClass;
00203         pClass=(CWin32Thread*)lpData;
00204         
00205         
00206         pClass->SetThreadStatus(tsRunning);
00207 
00208         
00209         LPVOID pData;
00210         pData=pClass->GetData();
00211 
00212         
00213         LPGenericThreadProc lpProc;
00214         lpProc=pClass->GetThreadProc();
00215 
00216         
00217         BOOL bAutoDelete;
00218         bAutoDelete=pClass->GetAutoDelete();
00219 
00220         
00221         DWORD dwReturnValue;
00222 
00223         
00224         try
00225         {
00226             dwReturnValue=(*lpProc)(pData);
00227         }
00228         catch(...)
00229         {
00230         }
00231 
00232         
00233         if (bAutoDelete)
00234         {
00235             
00236             
00237             pClass->SetBruteTermination(FALSE);
00238 
00239             
00240             delete pClass;
00241         }
00242         
00243         else if (dwReturnValue!=THREAD_DO_NOTHING_EXIT_VALUE)
00244             
00245             pClass->SetThreadStatus(tsStopped);
00246 
00247         return dwReturnValue;
00248     }
00249     ERROR_HANDLER_STATIC_RETURN(CWin32Thread_Class,"Win32Thread",THREAD_DO_NOTHING_EXIT_VALUE)
00250 }
00251 
00252 BOOL CWin32Thread::SetPriority(CGenericThread::ThreadPriority aPriority)
00253 {
00254     try
00255     {
00256         static const int iThreadPriority[]={THREAD_PRIORITY_IDLE,
00257                                             THREAD_PRIORITY_LOWEST,
00258                                             THREAD_PRIORITY_BELOW_NORMAL,
00259                                             THREAD_PRIORITY_NORMAL,
00260                                             THREAD_PRIORITY_ABOVE_NORMAL,
00261                                             THREAD_PRIORITY_HIGHEST,
00262                                             THREAD_PRIORITY_TIME_CRITICAL};
00263 
00264         
00265         if (GetThreadStatus()==tsStopped)
00266         {
00267             
00268             
00269             DWORD dwThreadID;
00270 
00271             
00272             m_hThread=CreateThread(NULL,
00273                                    0,
00274                                    Win32Thread,
00275                                    this,
00276                                    CREATE_SUSPENDED,
00277                                    &dwThreadID);
00278 
00279             
00280             if (m_hThread)
00281             {
00282                 
00283                 SetThreadID(dwThreadID);
00284 
00285                 
00286                 SetThreadStatus(tsSuspended);
00287             }
00288             else
00289                 
00290                 return FALSE;
00291         }
00292 
00293         
00294         return SetThreadPriority(m_hThread,
00295                                  iThreadPriority[aPriority]);
00296     }
00297     ERROR_HANDLER_RETURN("SetPriority",FALSE)
00298 }
00299 
00300 CGenericThread::ThreadPriority CWin32Thread::GetPriority()const
00301 {
00302     try
00303     {
00304         
00305         if (!m_hThread)
00306             return CGenericThread::tpNormal;
00307 
00308         int iPriority;
00309 
00310         
00311         iPriority=GetThreadPriority(m_hThread);
00312 
00313         
00314         switch (iPriority)
00315         {
00316         case THREAD_PRIORITY_ABOVE_NORMAL:
00317             return CGenericThread::tpAboveNormal;
00318         case THREAD_PRIORITY_BELOW_NORMAL:
00319             return CGenericThread::tpBelowNormal;
00320         case THREAD_PRIORITY_HIGHEST:
00321             return CGenericThread::tpHighest;
00322         case THREAD_PRIORITY_IDLE:
00323             return CGenericThread::tpIdle;
00324         case THREAD_PRIORITY_LOWEST:
00325             return CGenericThread::tpLowest;
00326         case THREAD_PRIORITY_NORMAL:
00327             return CGenericThread::tpNormal;
00328         case THREAD_PRIORITY_TIME_CRITICAL:
00329             return CGenericThread::tpTimeCritical;
00330         default:
00331             return CGenericThread::tpNormal;
00332         }
00333     }
00334     ERROR_HANDLER_RETURN("GetPriority",CGenericThread::tpNormal)
00335 }
00336 
00337 BOOL CWin32Thread::IsInThread()const
00338 {
00339     return GetCurrentThreadId()==GetThreadID();
00340 }
00341 
00342 KOMODIA_NAMESPACE_END