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 "ManagedThread.h"
00038
00039 #include "ErrorHandlerMacros.h"
00040 #include "GenericEvent.h"
00041 #include "OSManager.h"
00042
00043 #ifdef _MEMORY_DEBUG
00044 #define new DEBUG_NEW
00045 #define malloc DEBUG_MALLOC
00046 static char THIS_FILE[] = __FILE__;
00047 #endif
00048
00049 KOMODIA_NAMESPACE_START
00050
00051 #define CManagedThread_Class "CManagedThread"
00052
00053 CManagedThread::CManagedThread(LPManagedThreadProc pProc) : CErrorHandler(),
00054 m_pThread(NULL),
00055 m_pUserProc(pProc),
00056 m_pEnterEvent(NULL),
00057 m_pExitEvent(NULL),
00058 m_dwThreadTimeout(20000),
00059 m_bDestructor(FALSE)
00060 {
00061 try
00062 {
00063
00064 SetName(CManagedThread_Class);
00065
00066
00067 m_pThread=COSManager::CreateThread(ManagedThread);
00068 }
00069 ERROR_HANDLER("CManagedThread")
00070 }
00071
00072 CManagedThread::~CManagedThread()
00073 {
00074 try
00075 {
00076
00077 m_bDestructor=TRUE;
00078
00079
00080 Stop();
00081 }
00082 ERROR_HANDLER("~CManagedThread")
00083 }
00084
00085 DWORD CManagedThread::ManagedThread(LPVOID lpData)
00086 {
00087 try
00088 {
00089
00090 CManagedThread* pClass;
00091 pClass=(CManagedThread*)lpData;
00092
00093
00094 BOOL bExit;
00095 bExit=FALSE;
00096
00097
00098 if (pClass->m_pEnterEvent)
00099 pClass->m_pEnterEvent->Set();
00100 else
00101 return FALSE;
00102
00103
00104 DWORD dwValue;
00105
00106
00107 try
00108 {
00109 dwValue=(*pClass->m_pUserProc)(pClass->m_pExitEvent,
00110 pClass->m_lpData);
00111 }
00112 catch (...)
00113 {
00114 dwValue=FALSE;
00115 }
00116
00117
00118 pClass->m_pEnterEvent->Set();
00119
00120
00121 return dwValue;
00122 }
00123 ERROR_HANDLER_STATIC_RETURN(CManagedThread_Class,"ManagedThread",FALSE)
00124 }
00125
00126 BOOL CManagedThread::Start(LPVOID lpData)
00127 {
00128 try
00129 {
00130
00131 if (m_pEnterEvent ||
00132 m_pExitEvent)
00133 {
00134
00135 ReportError("Start","Already running!");
00136
00137
00138 return FALSE;
00139 }
00140
00141
00142 m_pEnterEvent=COSManager::CreateEvent();
00143 m_pExitEvent=COSManager::CreateEvent();
00144
00145
00146 m_lpData=lpData;
00147
00148
00149 m_pThread->SetAutoDelete(TRUE);
00150
00151
00152 m_pThread->Start((LPVOID)this);
00153
00154
00155 if (m_pEnterEvent->Wait(m_dwThreadTimeout))
00156 {
00157
00158 ReportError("Start","Timeout waiting for thread!");
00159
00160
00161 delete m_pThread;
00162 m_pThread=COSManager::CreateThread(ManagedThread);
00163
00164
00165 delete m_pEnterEvent;
00166 m_pEnterEvent=NULL;
00167
00168 delete m_pExitEvent;
00169 m_pExitEvent=NULL;
00170
00171
00172 return FALSE;
00173 }
00174 else
00175 return TRUE;
00176 }
00177 ERROR_HANDLER_RETURN("Start",FALSE)
00178 }
00179
00180 BOOL CManagedThread::Stop()
00181 {
00182 try
00183 {
00184 if (m_bDestructor)
00185 if (!m_pEnterEvent ||
00186 !m_pExitEvent)
00187 {
00188
00189 delete m_pThread;
00190
00191
00192 return TRUE;
00193 }
00194 else
00195 ;
00196 else
00197
00198 if (!m_pEnterEvent ||
00199 !m_pExitEvent)
00200 {
00201
00202 ReportError("Stop","Not running!");
00203
00204
00205 return FALSE;
00206 }
00207
00208
00209 DWORD dwThreadID;
00210 dwThreadID=m_pThread->GetThreadID();
00211
00212
00213 m_pExitEvent->Set();
00214
00215
00216 if (GetCurrentThreadId()!=dwThreadID &&
00217 m_pEnterEvent->Wait(m_dwThreadTimeout))
00218 {
00219
00220 ReportError("Stop","Timeout waiting for thread!");
00221
00222
00223 delete m_pThread;
00224 }
00225
00226
00227 m_pThread=NULL;
00228
00229
00230 if (!m_bDestructor)
00231 m_pThread=COSManager::CreateThread(ManagedThread);
00232
00233
00234 delete m_pEnterEvent;
00235 m_pEnterEvent=NULL;
00236
00237 delete m_pExitEvent;
00238 m_pExitEvent=NULL;
00239
00240
00241 return TRUE;
00242 }
00243 ERROR_HANDLER_RETURN("Stop",FALSE)
00244 }
00245
00246 void CManagedThread::SetThreadTimeout(DWORD dwTimeout)
00247 {
00248 try
00249 {
00250
00251 m_dwThreadTimeout=dwTimeout;
00252 }
00253 ERROR_HANDLER("SetThreadTimeout")
00254 }
00255
00256 CGenericThread* CManagedThread::GetThread()const
00257 {
00258 return m_pThread;
00259 }
00260
00261 void CManagedThread::SetPriority(CGenericThread::ThreadPriority aPriority)
00262 {
00263 try
00264 {
00265
00266 m_pThread->SetPriority(aPriority);
00267 }
00268 ERROR_HANDLER("SetPriority")
00269 }
00270
00271 KOMODIA_NAMESPACE_END