00001 // DOCUMENT: Threading-Class 00002 // VERSION: $Revision: 1.6 $ 00003 // DATE: $Date: 2007-10-26 23:09:19 $ 00004 // AUTHOR: M.Beranek 00005 // COPYRIGHT: M.Beranek 00006 00007 #include <pthread.h> 00008 #include "Thread.h" 00009 00010 namespace SmtpThread 00011 { 00012 // -------------------------------------------------------------------------- 00013 /** 00014 * Default-Constructor. 00015 */ 00016 Thread::Thread() 00017 { 00018 // We are not running: 00019 _isRunning = false; 00020 00021 // Initialize a mutex: 00022 pthread_mutex_init( &_mutex, 0L ); 00023 } 00024 00025 00026 // -------------------------------------------------------------------------- 00027 /** 00028 * Default-Destructor. 00029 */ 00030 Thread::~Thread() 00031 { 00032 // If the thread is running: 00033 if( _isRunning ) 00034 { 00035 // Stop the thread: 00036 Stop(); 00037 } 00038 } 00039 00040 00041 // -------------------------------------------------------------------------- 00042 /** 00043 * Starts threading. 00044 * Threading begins with static mebmer-function "EntryPoint". 00045 */ 00046 int Thread::Start(void * arg) 00047 { 00048 // Store the argument in _arg: 00049 Arg( arg ); 00050 00051 /* The pthreads-library expects a standard C-function as entrypoint for 00052 * threading. As an argument to the entrypoint, we provide a pointer 00053 * to ourself. This way, we can call any member-function within the 00054 * static entrypoint. 00055 */ 00056 int code = pthread_create( 00057 & _ThreadId, // Thread-ID 00058 NULL, // Default-Attributes 00059 Thread::EntryPoint, // Threading-function 00060 this // Argument of threading-function is "this" 00061 ); 00062 00063 return code; 00064 } 00065 00066 00067 // -------------------------------------------------------------------------- 00068 /** 00069 * Protected member-function. 00070 * Gets called after "EntryPoint" 00071 */ 00072 int Thread::Run( void * arg ) 00073 { 00074 // Do some initialization: 00075 Setup(); 00076 00077 // Execute main event-loop: 00078 Execute( arg ); 00079 00080 // Return success: 00081 return 0; 00082 } 00083 00084 00085 // -------------------------------------------------------------------------- 00086 /** 00087 * Static Member-Function, begin of threading. 00088 * @param void* this_p Must be a pointer to ourself. 00089 * @return void* a pointer to ourself. 00090 */ 00091 void* Thread::EntryPoint( void* this_p ) 00092 { 00093 // Pointer to the threading-object: 00094 Thread * pt = ( Thread * ) this_p; 00095 00096 /* This method is static, so it does not know anything about 00097 * the object/class it is declared in. So we have no "this"- 00098 * pointer within here. To call a member-function of this 00099 * object/class, we use the provided pointer to ourself. 00100 * As the argument to "Run", we provide the previously 00101 * initialized argument by calling "pt->Arg()" which is 00102 * effectivly the same as "this->Arg()". 00103 */ 00104 pt->Run( pt->Arg() ); 00105 00106 // Return a pointer to ourself. 00107 return this_p; 00108 } 00109 00110 00111 // -------------------------------------------------------------------------- 00112 /** 00113 * Setup some data for the thread. 00114 */ 00115 void Thread::Setup() 00116 { 00117 // Set up a mutex. 00118 pthread_mutex_init( &_mutex, NULL ); 00119 00120 // We are now running. 00121 _isRunning = true; 00122 } 00123 00124 00125 // -------------------------------------------------------------------------- 00126 /** 00127 * Main execution of the thread goes here. 00128 * Must be overridden to do something usefull. 00129 */ 00130 void Thread::Execute( void * arg ) 00131 { 00132 00133 } 00134 00135 00136 // -------------------------------------------------------------------------- 00137 /** 00138 * Returns the thread-ID. 00139 * @return pthread_t thread-ID 00140 */ 00141 pthread_t Thread::getThreadId() 00142 { 00143 return _ThreadId; 00144 } 00145 00146 00147 // -------------------------------------------------------------------------- 00148 /** 00149 * Determines whether thread is running or not. 00150 * @return bool true / false = thread is running / is not running. 00151 */ 00152 bool Thread::isRunning() 00153 { 00154 return _isRunning; 00155 } 00156 00157 00158 // -------------------------------------------------------------------------- 00159 /** 00160 * Stops threading. 00161 */ 00162 void Thread::Stop() 00163 { 00164 // Toggle "_isRunning", so the "Execute"-function will stop whatever it 00165 // is doing. 00166 _isRunning = false; 00167 00168 // Wait for thread to finish and synchronize with the main program. 00169 pthread_join( _ThreadId, NULL ); 00170 00171 } 00172 00173 00174 // -------------------------------------------------------------------------- 00175 /** 00176 * Locks the mutex. 00177 */ 00178 void Thread::getLock() 00179 { 00180 // Lock the mutex: 00181 pthread_mutex_lock( &_mutex ); 00182 } 00183 00184 00185 // -------------------------------------------------------------------------- 00186 /** 00187 * Unlocks the mutex. 00188 */ 00189 void Thread::releaseLock() 00190 { 00191 // Unlock the mutex: 00192 pthread_mutex_unlock( &_mutex ); 00193 } 00194 00195 }
1.5.1