Main Page   Modules   Namespace List   Class Hierarchy   Alphabetical List   Compound List   File List   Namespace Members   Compound 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.6 2003/08/16 13:23:58 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 
00102    bool wait( OSMutexBase &mtx, CleanupItem guard ) {
00103       int res;
00104       OSMutexPthread *posmux = static_cast<OSMutexPthread *>( &mtx );
00105       if ( guard.first != 0 ) {
00106          pthread_cleanup_push( wefts_pthread_cond_guard, &guard );
00107          res = (pthread_cond_wait( &m_cond, &( posmux->m_mutex ) ) == 0);
00108          pthread_cleanup_pop( 0 );
00109       }
00110       else
00111          res = (pthread_cond_wait( &m_cond, &( posmux->m_mutex ) ) == 0);
00112       return res;
00113    }
00114 
00116    bool timedWait( OSMutexBase &mtx, long seconds, long nanoseconds,
00117          CleanupItem guard  ) {
00118       int res;
00119       struct timeval now;
00120       struct timespec timeout;
00121       OSMutexPthread *posmux = static_cast<OSMutexPthread *>( &mtx );
00122 
00123       gettimeofday(&now, NULL);
00124       timeout.tv_sec = now.tv_sec + seconds;
00125       timeout.tv_nsec = now.tv_usec * 1000 + nanoseconds;
00126 
00127       if ( guard.first != 0 ) {
00128          pthread_cleanup_push( wefts_pthread_cond_guard, &guard );
00129          res = ( pthread_cond_timedwait( &m_cond, &( posmux->m_mutex ), &timeout ) == 0);
00130          pthread_cleanup_pop( 0 );
00131       }
00132       else
00133          res = ( pthread_cond_timedwait( &m_cond, &( posmux->m_mutex ), &timeout ) == 0);
00134 
00135       return res;
00136    }
00137 
00138 };
00139 
00143 class OSThreadPthread: public OSThreadBase {
00144 private:
00146    pthread_t   m_thid;
00148    bool m_valid;
00149 
00150 public:
00151    OSThreadPthread(): OSThreadBase() { invalidate(); }
00152    OSThreadPthread( bool val ): OSThreadBase( val ) {  setCurrent(); }
00153 
00154    bool start( void *(*func)(void *), void *data ) {
00155       return (pthread_create( &m_thid, 0, func, data ) == 0);
00156    }
00157 
00158    bool stop() { return (pthread_cancel( m_thid ) == 0); }
00159 
00160    void *join() throw( NotJoinableError ) {
00161       void *ret;
00162       int retval = pthread_join( m_thid, &ret );
00163       if ( retval != 0 ) throw NotJoinableError( retval );
00164       return ret;
00165    }
00166 
00167    int enableCancel(){
00168       int old_state;
00169       if ( pthread_setcancelstate( PTHREAD_CANCEL_ENABLE , &old_state ) == 0)
00170          return old_state;
00171       return -1; // currently does not matter if this is not correct.
00172    }
00173 
00174    int disableCancel() {
00175       int old_state;
00176       if ( pthread_setcancelstate( PTHREAD_CANCEL_DISABLE , &old_state ) == 0)
00177          return old_state;
00178       return -1; // currently does not matter if this is not correct.
00179    }
00180 
00181    bool setCancelState( int state ) {
00182       return (pthread_setcancelstate( state , 0 ) == 0);
00183    }
00184 
00185    void testCancel() { pthread_testcancel(); }
00186    void setCancelDeferred(){pthread_setcanceltype( PTHREAD_CANCEL_DEFERRED, 0 );}
00187    void detach() { pthread_detach( m_thid ); }
00188    void exit( void *data ) { pthread_exit( data ); }
00189 
00190    bool same() const {
00191       return (m_valid && pthread_equal( pthread_self(), m_thid ));
00192    }
00193 
00194    bool equal( const OSThreadBase &th ) const {
00195       const OSThreadPthread *other = static_cast<const OSThreadPthread *>( &th );
00196       return (m_valid && other->m_valid &&
00197             pthread_equal( other->m_thid, m_thid ) );
00198    }
00199 
00200    virtual bool setCurrent() { m_thid = pthread_self(); m_valid=true;}
00201 
00202    virtual void invalidate() { m_valid = false; }
00203 };
00204 
00206 class OSSpecificDataPthread: public OSSpecificDataBase
00207 {
00208 private:
00209    pthread_key_t  m_data;
00210 
00211 public:
00215    OSSpecificDataPthread() throw( InitError )
00216       :OSSpecificDataBase()
00217    {
00218       int res = pthread_key_create( &m_data, 0 );
00219       if ( res != 0 ) throw InitError( res );
00220    }
00221 
00226    ~OSSpecificDataPthread() { pthread_key_delete( m_data ); }
00227 
00228    void *data() const { return pthread_getspecific( m_data ); }
00229 
00230    void data(const void *dt) { pthread_setspecific( m_data, dt ); }
00231 };
00232 
00234 inline void OSPushCleanupAndExecute(
00235    void (*runner)(void *),
00236    void (*cleaner)(void *),
00237    void *data )
00238 {
00239    pthread_cleanup_push( cleaner, data );
00240    runner( data );
00241    pthread_cleanup_pop( 1 ); // execute cleanup
00242 }
00243 
00244 
00245 typedef OSSpecificDataPthread OSSpecificData;
00246 typedef OSThreadPthread OSThread;
00247 typedef OSConditionPthread OSCondition;
00248 typedef OSMutexPthread OSMutex;
00249 
00251 } // namespace
00252 
00253 #endif
00254 
00255 /* end of wefts_os_pthread.h */

Generated on Mon Aug 18 05:53:37 2003 for Wefts by doxygen1.2.18