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