wefts_os_pthread.h

Go to the documentation of this file.
00001 /* 00002 wefts_os_pthread.h 00003 Includes all the system dependant libraries for unix. 00004 00005 $Id: wefts_os_pthread.h,v 1.15 2004/03/28 21:45:40 jonnymind Exp $ 00006 --------------------------------------------- 00007 Begin : 2003-08-03 17:50 00008 Author : Giancarlo Niccolai 00009 00010 Last modified because: 00011 Implementing two-conditions read-write mutexes 00012 00013 */ 00014 00015 /************************************************************************** 00016 * This program is free software; you can redistribute it and/or modify * 00017 * it under the terms of the GNU Library General Public License as * 00018 * published by the Free Software Foundation; either version 2.1 of the * 00019 * License, or (at your option) any later version. * 00020 ***************************************************************************/ 00021 00022 00023 #ifndef WT_OS_PTHREAD_H 00024 #define WT_OS_PTHREAD_H 00025 00026 #include <wefts_cleanup.h> 00027 #include <wefts_os_base.h> 00028 #include <wefts_error.h> 00029 00030 #ifdef __extern_c 00031 extern "C" { 00032 #endif 00033 00034 #include <pthread.h> 00035 #include <sys/time.h> 00036 00037 #ifdef __extern_c 00038 } 00039 #endif 00040 00046 namespace Wefts { 00047 00055 void wefts_pthread_cond_guard( void *param ); 00056 void wefts_pthread_cond_reset( void *param ); 00057 00058 class OSMutexPthread: public OSMutexBase { 00059 protected: 00060 pthread_mutex_t m_mutex; 00061 00062 friend class OSConditionPthread; 00063 public: 00064 OSMutexPthread() throw( InitError ) 00065 : OSMutexBase() 00066 { 00067 int res = pthread_mutex_init( &m_mutex, NULL ); 00068 if ( res != 0 ) throw InitError( res ); 00069 } 00070 00071 ~OSMutexPthread() { pthread_mutex_destroy( &m_mutex ); } 00072 00073 virtual inline void lock() { pthread_mutex_lock( &m_mutex); } 00074 00075 virtual inline bool trylock() { return (pthread_mutex_trylock( &m_mutex) == 0); } 00076 00078 virtual inline void unlock() { pthread_mutex_unlock( &m_mutex ); } 00079 }; 00080 00085 class OSConditionPthread: public OSConditionBase { 00086 private: 00087 pthread_cond_t m_cond; 00088 00089 public: 00090 OSConditionPthread() throw( InitError ) 00091 : OSConditionBase() 00092 { 00093 int res = pthread_cond_init( &m_cond, NULL ); 00094 if ( res != 0 ) throw InitError( res ); 00095 } 00096 00097 ~OSConditionPthread() { pthread_cond_destroy( &m_cond ); } 00098 00099 void signal() { pthread_cond_broadcast( &m_cond ); } 00100 void signalOne() { pthread_cond_signal( &m_cond ); } 00101 00103 bool wait( OSMutexBase &mtx, CleanupItem &guard ) { 00104 int res; 00105 OSMutexPthread *posmux = static_cast<OSMutexPthread *>( &mtx ); 00106 if ( guard.handler != 0 ) { 00107 pthread_cleanup_push( wefts_pthread_cond_guard, &guard ); 00108 res = (pthread_cond_wait( &m_cond, &( posmux->m_mutex ) ) == 0); 00109 pthread_cleanup_pop( 0 ); 00110 } 00111 else 00112 res = (pthread_cond_wait( &m_cond, &( posmux->m_mutex ) ) == 0); 00113 return res; 00114 } 00115 00117 bool timedWait( OSMutexBase &mtx, long seconds, long nanoseconds, 00118 CleanupItem &guard ) { 00119 int res; 00120 struct timeval now; 00121 struct timespec timeout; 00122 OSMutexPthread *posmux = static_cast<OSMutexPthread *>( &mtx ); 00123 00124 gettimeofday(&now, NULL); 00125 timeout.tv_sec = now.tv_sec + seconds; 00126 timeout.tv_nsec = now.tv_usec * 1000 + nanoseconds; 00127 00128 if ( guard.handler != 0 ) { 00129 pthread_cleanup_push( wefts_pthread_cond_guard, &guard ); 00130 res = ( pthread_cond_timedwait( &m_cond, &( posmux->m_mutex ), &timeout ) == 0); 00131 pthread_cleanup_pop( 0 ); 00132 } 00133 else 00134 res = ( pthread_cond_timedwait( &m_cond, &( posmux->m_mutex ), &timeout ) == 0); 00135 00136 return res; 00137 } 00138 00139 }; 00140 00144 class OSThreadPthread: public OSThreadBase { 00145 private: 00147 pthread_t m_thid; 00149 bool m_valid; 00150 00151 public: 00152 OSThreadPthread(): OSThreadBase() { invalidate(); } 00153 OSThreadPthread( bool val ): OSThreadBase( val ) { setCurrent(); } 00154 00155 virtual bool priority( OSPriority prio_class, int boost = 0); 00156 00157 bool start( void *(*func)(void *), void *data ) { 00158 return (pthread_create( &m_thid, 0, func, data ) == 0); 00159 } 00160 00161 bool stop() { return (pthread_cancel( m_thid ) == 0); } 00162 00163 void *join() throw( NotJoinableError ) 00164 { 00165 void *ret; 00166 int retval = pthread_join( m_thid, &ret ); 00167 if ( retval != 0 ) throw NotJoinableError( retval ); 00168 return ret; 00169 } 00170 00171 int enableCancel() 00172 { 00173 int old_state; 00174 if ( pthread_setcancelstate( PTHREAD_CANCEL_ENABLE , &old_state ) == 0) 00175 return old_state; 00176 return -1; // currently does not matter if this is not correct. 00177 } 00178 00179 int disableCancel() 00180 { 00181 int old_state; 00182 if ( pthread_setcancelstate( PTHREAD_CANCEL_DISABLE , &old_state ) == 0) 00183 return old_state; 00184 return -1; // currently does not matter if this is not correct. 00185 } 00186 00187 bool setCancelState( int state ) { 00188 return (pthread_setcancelstate( state , 0 ) == 0); 00189 } 00190 00191 virtual inline void *osRun( void * (*runner)(void *), void *data, void (*cleaner)(void *)) 00192 { 00193 // initially, set return value to 0 00194 ThreadAndReturn thret = { data, 0 }; 00195 pthread_cleanup_push( cleaner, &thret ); 00196 thret.runReturn = runner( data ); 00197 pthread_cleanup_pop( 1 ); 00198 return thret.runReturn; 00199 } 00200 00201 00202 void testCancel() { pthread_testcancel(); } 00203 void setCancelDeferred(){pthread_setcanceltype( PTHREAD_CANCEL_DEFERRED, 0 );} 00204 void detach() { pthread_detach( m_thid ); } 00205 void exit( void *data ) { pthread_exit( data ); } 00206 00207 bool same() const { 00208 return (m_valid && pthread_equal( pthread_self(), m_thid )); 00209 } 00210 00211 bool equal( const OSThreadBase &th ) const { 00212 const OSThreadPthread *other = static_cast<const OSThreadPthread *>( &th ); 00213 return (m_valid && other->m_valid && 00214 pthread_equal( other->m_thid, m_thid ) ); 00215 } 00216 00217 virtual bool setCurrent() { m_thid = pthread_self(); m_valid=true;} 00218 00219 virtual void invalidate() { m_valid = false; } 00220 }; 00221 00223 class OSSpecificDataPthread: public OSSpecificDataBase 00224 { 00225 private: 00226 pthread_key_t m_data; 00227 00228 public: 00232 OSSpecificDataPthread() throw( InitError ) 00233 :OSSpecificDataBase() 00234 { 00235 int res = pthread_key_create( &m_data, 0 ); 00236 if ( res != 0 ) throw InitError( res ); 00237 } 00238 00243 ~OSSpecificDataPthread() { pthread_key_delete( m_data ); } 00244 00245 void *data() const { return pthread_getspecific( m_data ); } 00246 00247 void data(const void *dt) { pthread_setspecific( m_data, dt ); } 00248 }; 00249 00253 typedef OSSpecificDataPthread OSSpecificData; 00254 typedef OSThreadPthread OSThread; 00255 typedef OSConditionPthread OSCondition; 00256 typedef OSMutexPthread OSMutex; 00257 00259 } // namespace 00260 00261 #endif 00262 00263 /* end of wefts_os_pthread.h */

Generated on Tue Oct 5 14:57:00 2004 for Wefts by doxygen 1.3.7