Main Page   Modules   Namespace List   Class Hierarchy   Alphabetical List   Compound List   File List   Namespace Members   Compound 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.9 2003/12/14 09:41:55 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    virtual inline void osRun( void (*runner)(void *), void *data, void (*cleaner)(void *))
00186    {
00187       pthread_cleanup_push( cleaner, data );
00188       runner( data );
00189       pthread_cleanup_pop( 1 );
00190    }
00191 
00192 
00193    void testCancel() { pthread_testcancel(); }
00194    void setCancelDeferred(){pthread_setcanceltype( PTHREAD_CANCEL_DEFERRED, 0 );}
00195    void detach() { pthread_detach( m_thid ); }
00196    void exit( void *data ) { pthread_exit( data ); }
00197 
00198    bool same() const {
00199       return (m_valid && pthread_equal( pthread_self(), m_thid ));
00200    }
00201 
00202    bool equal( const OSThreadBase &th ) const {
00203       const OSThreadPthread *other = static_cast<const OSThreadPthread *>( &th );
00204       return (m_valid && other->m_valid &&
00205             pthread_equal( other->m_thid, m_thid ) );
00206    }
00207 
00208    virtual bool setCurrent() { m_thid = pthread_self(); m_valid=true;}
00209 
00210    virtual void invalidate() { m_valid = false; }
00211 };
00212 
00214 class OSSpecificDataPthread: public OSSpecificDataBase
00215 {
00216 private:
00217    pthread_key_t  m_data;
00218 
00219 public:
00223    OSSpecificDataPthread() throw( InitError )
00224       :OSSpecificDataBase()
00225    {
00226       int res = pthread_key_create( &m_data, 0 );
00227       if ( res != 0 ) throw InitError( res );
00228    }
00229 
00234    ~OSSpecificDataPthread() { pthread_key_delete( m_data ); }
00235 
00236    void *data() const { return pthread_getspecific( m_data ); }
00237 
00238    void data(const void *dt) { pthread_setspecific( m_data, dt ); }
00239 };
00240 
00244 typedef OSSpecificDataPthread OSSpecificData;
00245 typedef OSThreadPthread OSThread;
00246 typedef OSConditionPthread OSCondition;
00247 typedef OSMutexPthread OSMutex;
00248 
00250 } // namespace
00251 
00252 #endif
00253 
00254 /* end of wefts_os_pthread.h */

Generated on Mon Dec 22 04:12:30 2003 for Wefts by doxygen1.2.18