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 {
00165
00166 CloseHandle(m_hThread);
00167
00168
00169 m_hThread=NULL;
00170
00171
00172 return FALSE;
00173 }
00174
00175
00176 if (GetThreadStatus()==tsSuspended ||
00177 GetThreadStatus()==tsRunning)
00178 if (CloseHandle(m_hThread))
00179 {
00180
00181 m_hThread=NULL;
00182
00183
00184 SetThreadStatus(tsStopped);
00185
00186
00187 return TRUE;
00188 }
00189 else
00190 return FALSE;
00191 else
00192 {
00193
00194 if (CloseHandle(m_hThread))
00195 m_hThread=NULL;
00196
00197
00198 return FALSE;
00199 }
00200 }
00201 else
00202 return FALSE;
00203 }
00204 ERROR_HANDLER_RETURN("Stop",FALSE)
00205 }
00206
00207 DWORD WINAPI CWin32Thread::Win32Thread(LPVOID lpData)
00208 {
00209 try
00210 {
00211
00212 CWin32Thread* pClass;
00213 pClass=(CWin32Thread*)lpData;
00214
00215
00216 pClass->SetThreadStatus(tsRunning);
00217
00218
00219 LPVOID pData;
00220 pData=pClass->GetData();
00221
00222
00223 LPGenericThreadProc lpProc;
00224 lpProc=pClass->GetThreadProc();
00225
00226
00227 BOOL bAutoDelete;
00228 bAutoDelete=pClass->GetAutoDelete();
00229
00230
00231 DWORD dwReturnValue;
00232
00233
00234 try
00235 {
00236 dwReturnValue=(*lpProc)(pData);
00237 }
00238 catch(...)
00239 {
00240 }
00241
00242
00243 if (bAutoDelete)
00244 {
00245
00246
00247 pClass->SetBruteTermination(FALSE);
00248
00249
00250 delete pClass;
00251 }
00252
00253 else if (dwReturnValue!=THREAD_DO_NOTHING_EXIT_VALUE)
00254
00255 pClass->SetThreadStatus(tsStopped);
00256
00257 return dwReturnValue;
00258 }
00259 ERROR_HANDLER_STATIC_RETURN(CWin32Thread_Class,"Win32Thread",THREAD_DO_NOTHING_EXIT_VALUE)
00260 }
00261
00262 BOOL CWin32Thread::SetPriority(CGenericThread::ThreadPriority aPriority)
00263 {
00264 try
00265 {
00266 static const int iThreadPriority[]={THREAD_PRIORITY_IDLE,
00267 THREAD_PRIORITY_LOWEST,
00268 THREAD_PRIORITY_BELOW_NORMAL,
00269 THREAD_PRIORITY_NORMAL,
00270 THREAD_PRIORITY_ABOVE_NORMAL,
00271 THREAD_PRIORITY_HIGHEST,
00272 THREAD_PRIORITY_TIME_CRITICAL};
00273
00274
00275 if (GetThreadStatus()==tsStopped)
00276 {
00277
00278
00279 DWORD dwThreadID;
00280
00281
00282 m_hThread=CreateThread(NULL,
00283 0,
00284 Win32Thread,
00285 this,
00286 CREATE_SUSPENDED,
00287 &dwThreadID);
00288
00289
00290 if (m_hThread)
00291 {
00292
00293 SetThreadID(dwThreadID);
00294
00295
00296 SetThreadStatus(tsSuspended);
00297 }
00298 else
00299
00300 return FALSE;
00301 }
00302
00303
00304 return SetThreadPriority(m_hThread,
00305 iThreadPriority[aPriority]);
00306 }
00307 ERROR_HANDLER_RETURN("SetPriority",FALSE)
00308 }
00309
00310 CGenericThread::ThreadPriority CWin32Thread::GetPriority()const
00311 {
00312 try
00313 {
00314
00315 if (!m_hThread)
00316 return CGenericThread::tpNormal;
00317
00318 int iPriority;
00319
00320
00321 iPriority=GetThreadPriority(m_hThread);
00322
00323
00324 switch (iPriority)
00325 {
00326 case THREAD_PRIORITY_ABOVE_NORMAL:
00327 return CGenericThread::tpAboveNormal;
00328 case THREAD_PRIORITY_BELOW_NORMAL:
00329 return CGenericThread::tpBelowNormal;
00330 case THREAD_PRIORITY_HIGHEST:
00331 return CGenericThread::tpHighest;
00332 case THREAD_PRIORITY_IDLE:
00333 return CGenericThread::tpIdle;
00334 case THREAD_PRIORITY_LOWEST:
00335 return CGenericThread::tpLowest;
00336 case THREAD_PRIORITY_NORMAL:
00337 return CGenericThread::tpNormal;
00338 case THREAD_PRIORITY_TIME_CRITICAL:
00339 return CGenericThread::tpTimeCritical;
00340 default:
00341 return CGenericThread::tpNormal;
00342 }
00343 }
00344 ERROR_HANDLER_RETURN("GetPriority",CGenericThread::tpNormal)
00345 }
00346
00347 BOOL CWin32Thread::IsInThread()const
00348 {
00349 return GetCurrentThreadId()==GetThreadID();
00350 }
00351
00352 KOMODIA_NAMESPACE_END