Equalizer 1.0

perThreadRef.h

00001 
00002 /* Copyright (c) 2008-2011, Stefan Eilemann <eile@equalizergraphics.com> 
00003  *
00004  * This library is free software; you can redistribute it and/or modify it under
00005  * the terms of the GNU Lesser General Public License version 2.1 as published
00006  * by the Free Software Foundation.
00007  *  
00008  * This library is distributed in the hope that it will be useful, but WITHOUT
00009  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
00010  * FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more
00011  * details.
00012  * 
00013  * You should have received a copy of the GNU Lesser General Public License
00014  * along with this library; if not, write to the Free Software Foundation, Inc.,
00015  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
00016  */
00017 
00018 #ifndef COBASE_PERTHREADREF_H
00019 #define COBASE_PERTHREADREF_H
00020 
00021 #include <co/base/debug.h>
00022 #include <co/base/refPtr.h>
00023 
00024 namespace co
00025 {
00026 namespace base
00027 {
00028     class PerThreadRefPrivate;
00029 
00038     template< typename T > class PerThreadRef : public NonCopyable
00039     {
00040     public:
00042         PerThreadRef();
00044         ~PerThreadRef();
00045 
00047         PerThreadRef<T>& operator = ( RefPtr< T > data );
00048 
00050         PerThreadRef<T>& operator = ( const PerThreadRef<T>& rhs );
00051 
00053         RefPtr< const T > get() const;
00055         RefPtr< T > get();
00056 
00061         T* getPointer();
00062 
00067         T* operator->();
00068 
00073         const T* operator->() const;
00074 
00079         bool operator == ( const PerThreadRef& rhs ) const 
00080             { return ( get() == rhs.get( )); }
00081 
00086         bool operator == ( const RefPtr< T >& rhs ) const
00087             { return ( get()==rhs ); }
00088 
00093         bool operator != ( const RefPtr< T >& rhs ) const
00094             { return ( get()!=rhs ); }
00095 
00100         bool operator ! () const;
00101 
00106         bool isValid() const;
00107 
00108     private:
00109         PerThreadRefPrivate* _data;
00110     };
00111 
00112 
00113 //----------------------------------------------------------------------
00114 // implementation
00115 //----------------------------------------------------------------------
00116 
00117 // Crude test if pthread.h was included
00118 #ifdef PTHREAD_MUTEX_INITIALIZER
00119 #  ifndef HAVE_PTHREAD_H
00120 #    define HAVE_PTHREAD_H
00121 #  endif
00122 #endif
00123 
00124 #ifdef HAVE_PTHREAD_H
00125 
00126 class PerThreadRefPrivate
00127 {
00128 public:
00129     pthread_key_t key;
00130 };
00131 
00132 template< typename T >
00133 PerThreadRef<T>::PerThreadRef() 
00134         : _data( new PerThreadRefPrivate )
00135 {
00136     const int error = pthread_key_create( &_data->key, 0 );
00137     if( error )
00138     {
00139         EQERROR << "Can't create thread-specific key: " 
00140                 << strerror( error ) << std::endl;
00141         EQASSERT( !error );
00142     }
00143 }
00144 
00145 template< typename T >
00146 PerThreadRef<T>::~PerThreadRef()
00147 {
00148     RefPtr< T > object = get();
00149 
00150     pthread_key_delete( _data->key );
00151     delete _data;
00152     _data = 0;
00153 
00154     object.unref();
00155 }
00156 
00157 template< typename T >
00158 PerThreadRef<T>& PerThreadRef<T>::operator = ( RefPtr< T > data )
00159 { 
00160     data.ref(); // ref new
00161 
00162     RefPtr< T > object = get();
00163     pthread_setspecific( _data->key, static_cast<const void*>( data.get( )));
00164 
00165     object.unref(); // unref old
00166     return *this; 
00167 }
00168 
00169 template< typename T >
00170 PerThreadRef<T>& PerThreadRef<T>::operator = ( const PerThreadRef<T>& rhs )
00171 {
00172     RefPtr< T > newObject = rhs.get();
00173     newObject.ref(); // ref new
00174 
00175     RefPtr< T > object = get();
00176     pthread_setspecific( _data->key, pthread_getspecific( rhs._data->key ));
00177 
00178     object.unref(); // unref old
00179     return *this;
00180 }
00181 
00182 template< typename T >
00183 RefPtr< const T > PerThreadRef<T>::get() const
00184 {
00185     return static_cast< const T* >( pthread_getspecific( _data->key )); 
00186 }
00187 
00188 template< typename T >
00189 RefPtr< T > PerThreadRef<T>::get()
00190 {
00191     return static_cast< T* >( pthread_getspecific( _data->key )); 
00192 }
00193 
00194 template< typename T >
00195 T* PerThreadRef<T>::getPointer()
00196 {
00197     return static_cast< T* >( pthread_getspecific( _data->key )); 
00198 }
00199 
00200 template< typename T >
00201 T* PerThreadRef<T>::operator->() 
00202 {
00203     EQASSERT( pthread_getspecific( _data->key ));
00204     return static_cast< T* >( pthread_getspecific( _data->key )); 
00205 }
00206 
00207 template< typename T >
00208 const T* PerThreadRef<T>::operator->() const 
00209 { 
00210     EQASSERT( pthread_getspecific( _data->key ));
00211     return static_cast< const T* >( pthread_getspecific( _data->key )); 
00212 }
00213 
00214 template< typename T >
00215 bool PerThreadRef<T>::operator ! () const
00216 {
00217     return pthread_getspecific( _data->key ) == 0;
00218 }
00219 
00220 template< typename T >
00221 bool PerThreadRef<T>::isValid() const
00222 {
00223     return pthread_getspecific( _data->key ) != 0;
00224 }
00225 
00226 #endif // HAVE_PTHREAD_H
00227 }
00228 
00229 }
00230 #endif //COBASE_PERTHREADREF_H
Generated on Sun May 8 2011 19:11:07 for Equalizer 1.0 by  doxygen 1.7.3