Equalizer 1.0
|
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