00001 /* 00002 * This file contains class that encapsulates system thread. 00003 * 00004 * Author: 00005 * Tomas Mrkvicka 00006 * xmrkvi03@stud.fit.vutbr.cz 00007 * 00008 */ 00009 00010 #include <cassert> 00011 00012 #include "pipeline/Thread.h" 00013 00014 //////////////////////////////////////////////////////////////////////////////// 00015 //////////////////////////////////////////////////////////////////////////////// 00016 //////////////////////////////////////////////////////////////////////////////// 00017 // TThread 00018 00019 /** Spusteni vlakna na prislusne funkci a s pozadovanym parametrem. 00020 * 00021 * Vlakno lze spustit pouze jednou. Po uspesnem spusteni jiz dalsi 00022 * volani teto metody vraci TRUE a nic se nedeje. 00023 * 00024 * Novou funkci lze spustit teprve po uspesnem ukonceni vlakna - tj. metoda IsTerminated() 00025 * vrati nejprve TRUE a nasledne je pomoci metody Finish() objekt uveden do pocatecniho stavu. 00026 * 00027 * Metoda vraci TRUE pokud bylo vlakno uspesne spusteno nebo pokud jiz nejake vlakno bezi. 00028 * Metoda vrati FALSE v pripade, ze nelze vytvorit nove vlakno, coz je kriticka chyba. 00029 * 00030 * \warning Funkce spoustena vlaknem musi vracet hodnotu typu DWORD. Tato hodnota 00031 * nesmi byt v zadnem pripade shodna s hodnotou STILL_ACTIVE. V tom pripade by totiz 00032 * nebylo mozne rozeznat jiz dokoncenou funkci. 00033 * 00034 * \param function [in] ukazatel na funkci, ktera bude nad vlaknem spustena 00035 * \param param [in] ukazatel na parametry - funkce musi znat spravny 00036 * typ a podle toho provest pretypovani 00037 */ 00038 BOOL TThread::Run( FUNC_PTR function, void * params ) 00039 { 00040 if( ! m_thread ) 00041 { 00042 //vlakno spustime pouze pokud jiz nejake pres tento objekt neni spustene 00043 00044 DWORD id; 00045 m_thread = CreateThread(NULL,0,(PTHREAD_START_ROUTINE)function,params,0,&id); 00046 00047 if( ! m_thread ) 00048 { 00049 return FALSE; 00050 } 00051 else 00052 { 00053 return TRUE; 00054 } 00055 } 00056 else 00057 { 00058 //vlakno uz bylo spusteno 00059 return TRUE; 00060 } 00061 } 00062 //OK 2007-08-25 00:11:43 B04-315B\Tom 00063 00064 /** Metoda urci zda bylo vlakno spusteno. 00065 * 00066 * \note Vlakno uz nemusi bezet, metoda pouze detekuje ze vlakno bylo spusteno (vytvoreno). 00067 */ 00068 BOOL TThread::IsRunning(void) const 00069 { 00070 return NULL != m_thread; 00071 } 00072 //OK 2007-08-25 00:17:26 B04-315B\Tom 00073 00074 /** Metoda urci zda bylo bezici vlakno ukonceno. 00075 * 00076 * Pokud vlakno nebylo vubec spusteno pak metoda vrati TRUE. 00077 * Metoda vraci FALSE pokud vlakno jeste bezi nebo v pripade nejake systemove chyby 00078 * vznikle v dusledku dotazu na vlakno.. 00079 */ 00080 BOOL TThread::IsTerminated(void) 00081 { 00082 if( m_thread ) 00083 { 00084 //vlakno bylo spusteno - proverime ukonceni 00085 DWORD res; 00086 if( ! GetExitCodeThread( m_thread, &res ) ) 00087 { 00088 //doslo k chybe, vlakno zrejme stale bezi, ale neni mozne ziskat informace 00089 //o behu 00090 00091 assert(false); 00092 return FALSE; 00093 } 00094 else 00095 { 00096 return res != STILL_ACTIVE; 00097 } 00098 } 00099 else 00100 { 00101 //vlakno nebezi 00102 return TRUE; 00103 } 00104 } 00105 //OK 2007-08-25 00:22:53 B04-315B\Tom 00106 00107 /** Metoda ukonci provadeni vlakna. 00108 * 00109 * Pokud vlakno jeste nebylo ukonceno pak metoda prerusi vlakno. 00110 * 00111 * Metoda vraci TRUE pokud bylo vlakno radne ukonceno. 00112 * 00113 * Tato metoda by mela byt volana pouze na vlakno, ktere vraci pri metode 00114 * TThread::IsTerminated() hodnotu TRUE. To znamena, ze funkce vlakna byla ukoncena 00115 * navratovou hodnotou a vlakno ceka na ukonceni. 00116 * 00117 * Pokud je metoda volana na vlakno, ktere stale bezi, pak dojde k ukonceni vlakna behem 00118 * provadeni, coz muze zpusobit napr. neuvolneni synchronizacnich mechanizmu (kriticke sekce, 00119 * semafory, apod). 00120 */ 00121 BOOL TThread::Terminate(void) 00122 { 00123 if(m_thread) 00124 { 00125 if( IsTerminated() ) 00126 { 00127 //vlakno uz bylo ukonceno 00128 CloseHandle( m_thread ); 00129 m_thread = NULL; 00130 return TRUE; 00131 } 00132 else 00133 { 00134 //musime vlakno ukoncit 00135 TerminateThread(m_thread, 1); 00136 CloseHandle( m_thread ); 00137 m_thread = NULL; 00138 return TRUE; 00139 } 00140 } 00141 else 00142 { 00143 //vlakno nebylo vubec vytvoreno 00144 return TRUE; 00145 } 00146 } 00147 //OK 2007-08-25 00:26:07 B04-315B\Tom 00148 00149 /** Metoda radne ukonci provadeni dokonceneho vlakna. 00150 * 00151 * Metoda smi byt volana pouze na ukoncene vlakno - tj. kdyz IsTerminated() vraci TRUE. 00152 * 00153 * Metoda vraci TRUE pokud bylo vlakno radne ukonceno, jinak FALSE. 00154 * 00155 * Po uspesnem zavolani teto metody (TRUE) je mozne spustit novou funkci. 00156 */ 00157 BOOL TThread::Finish(void) 00158 { 00159 if( m_thread ) 00160 { 00161 if( IsTerminated() ) 00162 { 00163 //vlakno uz bylo ukonceno 00164 CloseHandle( m_thread ); 00165 m_thread = NULL; 00166 return TRUE; 00167 } 00168 else 00169 { 00170 //vlakno nebylo ukonceno - nic se nedeje 00171 return FALSE; 00172 } 00173 } 00174 else 00175 { 00176 return TRUE; 00177 } 00178 } 00179 //OK 2007-08-25 00:26:11 B04-315B\Tom 00180 00181 // TThread 00182 //////////////////////////////////////////////////////////////////////////////// 00183 //////////////////////////////////////////////////////////////////////////////// 00184 ////////////////////////////////////////////////////////////////////////////////