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