Main Page | Modules | Namespace List | Class Hierarchy | Alphabetical List | Class List | File List | Namespace Members | Class Members | File Members | Related Pages

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.14 2004/03/13 15:21:05 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 Sat Mar 13 21:05:43 2004 for Wefts by doxygen 1.3.5