00001 /****************************************************************************** 00002 * __ _ _ _ _ _ _____ * 00003 * | \ / | | | | | | | | | | ___| * 00004 * | \/ | | | | | | | | | | |_ * 00005 * | | | | | | | | | | | _| * 00006 * | |\/| | | | | |__ | |__ | | | |__ * 00007 * |_| |_| |_| |____| |____| |_| |____| * 00008 * __________________________________________________________________________ * 00009 * Multifunctional Library For Image Processing * 00010 * * 00011 * * 00012 * * 00013 * (c) Copyright 2007 by Humbert Florent * 00014 * * 00015 * This program is free software; you can redistribute it and/or modify * 00016 * it under the terms of the GNU General Public License as published by * 00017 * the Free Software Foundation; only version 2 of the License. * 00018 * * 00019 * This program is distributed in the hope that it will be useful, * 00020 * but WITHOUT ANY WARRANTY; without even the implied warranty of * 00021 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 00022 * GNU General Public License for more details. * 00023 * * 00024 * You should have received a copy of the GNU General Public License * 00025 * along with this program; if not, write to the Free Software * 00026 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA * 00027 * 02111-1307, USA. * 00028 ******************************************************************************/ 00029 00030 00033 #include "Thread.hpp" 00034 00035 00036 using namespace Millie; 00037 00043 void * Millie::threadHandler(void * pthread) 00044 { 00045 Thread * current = static_cast<Thread*>(pthread); 00046 MutexLock mlock(current->_synchronizedRun); 00047 try 00048 { 00049 current->run(); 00050 } 00051 catch(std::exception& e) 00052 { 00053 std::cerr<<e.what()<<std::endl; 00054 } 00055 catch(...) 00056 { 00057 std::cerr<<"Failure"<<std::endl; 00058 } 00059 00060 MutexLock plock(current->_synchronizedIsAlive); 00061 current->_isAlive = false; 00062 return NULL; 00063 } 00064 00065 void Thread::init() 00066 { 00067 _isAlive = true; 00068 _isStarted = false; 00069 _wasJoined = false; 00070 pthread_cond_init(&_waitSynchro, 0); 00071 00072 00073 pthread_mutex_init(&_waitMutex, 0); 00074 pthread_mutex_init(&_mutexWaitAll, 0); 00075 00076 } 00077 00078 Thread::Thread() 00079 { 00080 init(); 00081 } 00082 00083 Thread::Thread(const std::string & name) 00084 { 00085 init(); 00086 _name = name; 00087 } 00088 00089 Thread::~Thread() 00090 { 00091 /*on ne rejoint pas et on prefère lancer une exception 00092 * qui montre une erreur de programmation. 00093 * De plus, il y a des problèmes si les classes qui héritent 00094 * sont détruites juste avant ~Thread(), les données pourraient être 00095 * incohérente. 00096 */ 00097 //join(); 00098 MutexLock lock(_synchronizedStart) 00099 ; 00100 00101 pthread_cond_destroy(&_waitSynchro); 00102 00103 pthread_mutex_destroy(&_waitMutex); 00104 pthread_mutex_destroy(&_mutexWaitAll); 00105 00106 00107 _isAlive = false; 00108 _isStarted = false; 00109 00110 if(!_wasJoined) 00111 throw IllegalThreadStateException("Thread was not joined"); 00112 } 00113 00114 bool Thread::isRunning() 00115 { 00116 MutexLock mlock(_synchronizedIsRunning); 00117 return _isRunning; 00118 } 00119 00120 00121 00122 void Thread::wait() 00123 { 00124 Mutex mlock(_synchronizedIsRunning); 00125 if(!_isRunning) 00126 throw IllegalThreadStateException("Thread : wait"); 00127 00128 pthread_mutex_lock(&_waitMutex); 00129 pthread_cond_wait(&_waitSynchro, &_waitMutex); 00130 pthread_mutex_unlock(&_waitMutex); 00131 } 00132 00133 void Thread::notify() 00134 { 00135 pthread_mutex_lock(&_waitMutex); 00136 pthread_cond_broadcast(&_waitSynchro); 00137 pthread_mutex_unlock(&_waitMutex); 00138 } 00139 00140 00141 bool Thread::isAlive() 00142 { 00143 MutexLock mlock(_synchronizedIsAlive); 00144 return _isAlive; 00145 } 00146 00147 void Thread::start() 00148 { 00149 MutexLock mstart(_synchronizedStart); 00150 00154 if(_isStarted) 00155 throw IllegalThreadStateException("Thread : still started"); 00156 00157 _isStarted = true; 00158 00159 MutexLock mlock(_synchronizedRun); 00160 MutexLock plock(_synchronizedIsRunning); 00161 00162 00163 _isRunning = true; 00164 00165 if(pthread_create(&_thread, NULL, threadHandler, this)!=0) 00166 { 00167 _isRunning = false; 00168 throw ThreadCreationFailed("Start : creation failed"); 00169 } 00170 00171 } 00172 00173 void Thread::join() 00174 { 00175 MutexLock lock(_synchronizedStart) 00176 ; 00177 if(_isStarted && !_wasJoined) 00178 pthread_join(_thread, NULL); 00179 00180 _wasJoined = true; 00181 /*sinon, il n'a jamais été lancé, on ne l'attend pas*/ 00182 } 00183 00184 ThreadID Thread::currentThread() 00185 { 00186 return static_cast<ThreadID>(pthread_self()); 00187 } 00188 00189 00190 const std::string & Thread::getName() const 00191 { 00192 return _name; 00193 } 00194 00195 00196 ThreadID Thread::getThreadId() const 00197 { 00198 return static_cast<ThreadID>(_thread); 00199 } 00200 00201