PCMPointer_impl.h

Go to the documentation of this file.
00001 
00002 //
00003 // This source file is a part of ParCompMark
00004 // Parallel Compositing Benchmark Framework
00005 //
00006 // for latest info see http://parcompmark.sourceforge.net
00007 
00008 //
00009 // Copyright (C) 2006 IT2 ParCompMark Dev. Team
00010 // 
00011 // This program is free software; you can redistribute it and/or
00012 // modify it under the terms of the GNU General Public License
00013 // as published by the Free Software Foundation; either version 2
00014 // of the License, or (at your option) any later version.
00015 // 
00016 // This program is distributed in the hope that it will be useful,
00017 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00018 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
00019 // GNU General Public License for more details.
00020 // 
00021 // You should have received a copy of the GNU General Public License
00022 // along with this program; if not, write to the Free Software
00023 // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
00024 
00027 
00028  //
00029  // Constructors & destructor
00030  //
00031 
00032 template < typename T, class Lock > inline Pointer < T, Lock >::Pointer()
00033   // You have to initialize the following attributes:
00034   // - mMeta
00035 {
00036   mMeta = new Meta();
00037   mMeta->ptr = 0;
00038   mMeta->dead = true;
00039   mMeta->usage = 1;
00040   mMeta->ownMemory = false;
00041 }
00042 
00043  /*----------------------------------------------------------------------*/
00044 
00045 template < typename T, class Lock > inline Pointer < T, Lock >::Pointer(const T * pointer,
00046                                                                         const bool & takeOwnership)
00047   // You have to initialize the following attributes:
00048   // - mMeta
00049 {
00050   _assignCPointer((T * &)pointer, takeOwnership);
00051 }
00052 
00053  /*----------------------------------------------------------------------*/
00054 
00055 template < typename T, class Lock > inline Pointer < T, Lock >::Pointer(Pointer < T, Lock > &pointer)
00056   // You have to initialize the following attributes:
00057   // - mMeta
00058 {
00059   _assignPointer(pointer);
00060 }
00061 
00062  /*----------------------------------------------------------------------*/
00063 
00064 template < typename T, class Lock > inline Pointer < T, Lock >::Pointer(const Pointer < T, Lock > &pointer)
00065   // You have to initialize the following attributes:
00066   // - mMeta
00067 {
00068   Pointer < T, Lock > &_pointer = (Pointer < T, Lock > &)pointer;
00069   _assignPointer(_pointer);
00070 }
00071 
00072  /*----------------------------------------------------------------------*/
00073 
00074 template < typename T, class Lock > Pointer < T, Lock >::~Pointer()
00075 {
00076   _deletePointer();
00077 }
00078 
00079  /*----------------------------------------------------------------------*/
00080 
00081  //
00082  // Operators
00083  //
00084 
00085 template < typename T, class Lock > inline const Pointer < T, Lock > &Pointer < T,
00086   Lock >::operator=(const T * pointer)
00087   // Implementation of operator =
00088 {
00089   if(!_equalsCPointer(pointer))
00090   {
00091         // Changing reference under continous lock
00092         _deletePointer(false, true);
00093         Meta *oldMeta = mMeta;
00094 
00095         _assignCPointer(pointer);
00096 
00097         // Release the previous and the current meta
00098         oldMeta->lock.unlock();
00099         unlock();
00100   }
00101 
00102   return *this;
00103 }
00104 
00105  /*----------------------------------------------------------------------*/
00106 
00107 template < typename T, class Lock > inline const Pointer < T, Lock > &Pointer < T, Lock >::operator=(Pointer < T,
00108                                                                                                          Lock >
00109                                                                                                          &pointer)
00110   // Implementation of operator =
00111 {
00112   if(!_equalsPointer(pointer))
00113         // Changing reference under continous lock
00114         _switchPointer(pointer, false);
00115 
00116   return *this;
00117 }
00118 
00119  /*----------------------------------------------------------------------*/
00120 
00121 template < typename T, class Lock > inline const Pointer < T, Lock > &Pointer < T,
00122   Lock >::operator=(const Pointer < T, Lock > &pointer)
00123   // Implementation of operator =
00124 {
00125   Pointer < T, Lock > &_pointer = (Pointer < T, Lock > &)pointer;
00126 
00127   if(!_equalsPointer(_pointer))
00128         // Changing reference under continous lock
00129         _switchPointer(_pointer, false);
00130 
00131   return *this;
00132 }
00133 
00134  /*----------------------------------------------------------------------*/
00135 
00136 template < typename T, class Lock > inline T * Pointer < T, Lock >::operator->()
00137   // Implementation of operator ->
00138 {
00139   Assert(this->isNotNull(), NULL_POINTER_ERROR, "Pointer::operator->");
00140   return mMeta->ptr;
00141 }
00142 
00143  /*----------------------------------------------------------------------*/
00144 
00154  /*----------------------------------------------------------------------*/
00155 
00164  /*----------------------------------------------------------------------*/
00165 
00175  /*----------------------------------------------------------------------*/
00176 
00177 template < typename T, class Lock > inline bool Pointer < T, Lock >::operator==(const T * pointer)
00178   // Implementation of operator ==
00179 {
00180   return _equalsCPointer(pointer);
00181 }
00182 
00183  /*----------------------------------------------------------------------*/
00184 
00185 template < typename T, class Lock > inline bool Pointer < T, Lock >::operator==(Pointer < T, Lock > &pointer)
00186   // Implementation of operator ==
00187 {
00188   return _equalsPointer(pointer);
00189 }
00190 
00191  /*----------------------------------------------------------------------*/
00192 
00193 template < typename T, class Lock > inline bool Pointer < T, Lock >::operator!=(const T * pointer)
00194   // Implementation of operator !=
00195 {
00196   return !_equalsCPointer(pointer);
00197 }
00198 
00199  /*----------------------------------------------------------------------*/
00200 
00201 template < typename T, class Lock > inline bool Pointer < T, Lock >::operator!=(Pointer < T, Lock > &pointer)
00202   // Implementation of operator !=
00203 {
00204   return !_equalsPointer(pointer);
00205 }
00206 
00207  /*----------------------------------------------------------------------*/
00208 
00209  //
00210  // Methods
00211  //
00212 
00213 template < typename T, class Lock > inline bool Pointer < T, Lock >::isNull()const
00214 {
00215   return mMeta->ptr == 0;
00216 }
00217 
00218  /*----------------------------------------------------------------------*/
00219 
00220 template < typename T, class Lock > inline bool Pointer < T, Lock >::isNotNull()const
00221 {
00222   return mMeta->ptr != 0;
00223 }
00224 
00225  /*----------------------------------------------------------------------*/
00226 
00227 template < typename T, class Lock > inline void Pointer < T,
00228  Lock >::assignWithLock(Pointer < T, Lock > &pointer)
00229 {
00230   // TODO: this method does not work correctly
00231   // deadlock between _deletePointer and _assingPointer
00232 
00233   if(!_equalsPointer(pointer))
00234         _switchPointer(pointer, true);
00235 
00236   else
00237         // Nothing to assing simply lock
00238         lock();
00239 }
00240 
00241  /*----------------------------------------------------------------------*/
00242 
00243 template < typename T, class Lock > inline void Pointer < T,
00244  Lock >::reference(const T * pointer)
00245 {
00246   if(!_equalsCPointer(pointer))
00247   {
00248         _deletePointer();
00249         _assignCPointer(pointer, false);
00250   }
00251 }
00252 
00253  /*----------------------------------------------------------------------*/
00254 
00255 template < typename T, class Lock > inline T * Pointer < T, Lock >::getPtr()
00256 {
00257   return mMeta->ptr;
00258 }
00259 
00260  /*----------------------------------------------------------------------*/
00261 
00262 template < typename T, class Lock > inline void Pointer < T,
00263  Lock >::kill(const bool & force)
00264 {
00265   // Null reference can not be 
00266   Assert(isNotNull() && mMeta->ownMemory, NULL_POINTER_ERROR, "Pointer::kill()");
00267 
00268   // Note: zero reference indicates error, positive is proper after null checking
00269   _deletePointer(force);
00270 }
00271 
00272  /*----------------------------------------------------------------------*/
00273 
00274 template < typename T, class Lock > inline void Pointer < T,
00275  Lock >::setNull(const bool & force)
00276 {
00277   lock();
00278   mMeta->ptr = 0;
00279   unlock();
00280 }
00281 
00282  /*----------------------------------------------------------------------*/
00283 
00284 template < typename T, class Lock > inline void Pointer < T,
00285  Lock >::lock()
00286 {
00287   mMeta->lock.lock();
00288 }
00289 
00290  /*----------------------------------------------------------------------*/
00291 
00292 template < typename T, class Lock > inline bool Pointer < T, Lock >::trylock()
00293 {
00294   return mMeta->lock.trylock();
00295 }
00296 
00297  /*----------------------------------------------------------------------*/
00298 
00299 template < typename T, class Lock > inline void Pointer < T,
00300  Lock >::unlock()
00301 {
00302   mMeta->lock.unlock();
00303 }
00304 
00305  /*----------------------------------------------------------------------*/
00306 
00307 template < typename T, class Lock > inline bool Pointer < T, Lock >::getLocked()const
00308 {
00309   return mMeta->lock.getLocked();
00310 }
00311 
00312  /*----------------------------------------------------------------------*/
00313 
00314 template < typename T, class Lock > inline void Pointer < T,
00315  Lock >::_deletePointer(const bool & force, const bool & keepLock)
00316 {
00317   // Always lock before deleting
00318   lock();
00319 
00320   // Decrement usage counter
00321   if(mMeta->usage)
00322         mMeta->usage--;
00323 
00324   // Abadoned object will be killed (or force killing)
00325   if(!mMeta->usage || force)
00326         mMeta->dead = true;
00327 
00328   // Deallocate memory
00329   if(mMeta->dead && mMeta->ownMemory && mMeta->ptr)
00330   {
00331         delete mMeta->ptr;
00332 
00333         mMeta->ptr = 0;
00334   }
00335   // Unlock if no further locking is needed
00336   if(!keepLock)
00337         unlock();
00338 }
00339 
00340  /*----------------------------------------------------------------------*/
00341 
00342 template < typename T, class Lock > inline void Pointer < T,
00343  Lock >::_assignCPointer(const T * pointer, const bool & takeOwnership)
00344 {
00345   // Possibly take ownership
00346   mMeta = new Meta();
00347   mMeta->ptr = (T *) pointer;
00348   mMeta->dead = !pointer;
00349   mMeta->usage = 1;
00350   mMeta->ownMemory = takeOwnership && pointer;
00351 }
00352 
00353  /*----------------------------------------------------------------------*/
00354 
00355 template < typename T, class Lock > inline void Pointer < T,
00356  Lock >::_assignPointer(Pointer < T, Lock > &pointer, const bool & keepLock)
00357 {
00358   pointer.lock();
00359   mMeta = pointer.mMeta;
00360   mMeta->usage++;
00361 
00362   // Unlock if no further locking is needed
00363   if(!keepLock)
00364         pointer.unlock();
00365 }
00366 
00367  /*----------------------------------------------------------------------*/
00368 
00369 template < typename T, class Lock > inline void Pointer < T,
00370  Lock >::_switchPointer(Pointer < T, Lock > &pointer, const bool & keepLock)
00371 {
00372   // Delete pointer keeping continous lock
00373   _deletePointer(false, true);
00374   Meta *oldMeta = mMeta;
00375 
00376   _assignPointer(pointer, true);
00377 
00378   // Release the previous meta
00379   oldMeta->lock.unlock();
00380 
00381   // Release new meta
00382   if(!keepLock)
00383         unlock();
00384 }
00385 
00386  /*----------------------------------------------------------------------*/
00387 
00388 template < typename T, class Lock > inline bool Pointer < T,
00389   Lock >::_equalsCPointer(const T * pointer) const
00390 {
00391   return mMeta->ptr == pointer;
00392 }
00393 
00394  /*----------------------------------------------------------------------*/
00395 
00396 template < typename T, class Lock > inline bool Pointer < T, Lock >::_equalsPointer(Pointer < T,
00397                                                                                  Lock > &pointer) const
00398 {
00399   return mMeta->ptr == pointer.mMeta->ptr;
00400 }
00401 
00402  /*----------------------------------------------------------------------*/