Fawkes API  Fawkes Development Version
rwlock_vector.h
00001 
00002 /***************************************************************************
00003  *  rwlock_vector.h - Vector with read/write lock
00004  *
00005  *  Created: Mon Jan 10 11:35:24 2011
00006  *  Copyright  2006-2011  Tim Niemueller [www.niemueller.de]
00007  *
00008  ****************************************************************************/
00009 
00010 /*  This program is free software; you can redistribute it and/or modify
00011  *  it under the terms of the GNU General Public License as published by
00012  *  the Free Software Foundation; either version 2 of the License, or
00013  *  (at your option) any later version. A runtime exception applies to
00014  *  this software (see LICENSE.GPL_WRE file mentioned below for details).
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 Library General Public License for more details.
00020  *
00021  *  Read the full text in the LICENSE.GPL_WRE file in the doc directory.
00022  */
00023 
00024 #ifndef __CORE_UTILS_RWLOCK_VECTOR_H_
00025 #define __CORE_UTILS_RWLOCK_VECTOR_H_
00026 
00027 #include <core/threading/read_write_lock.h>
00028 #include <core/utils/refptr.h>
00029 #include <vector>
00030 
00031 namespace fawkes {
00032 #if 0 /* just to make Emacs auto-indent happy */
00033 }
00034 #endif
00035 
00036 template <typename Type>
00037 class RWLockVector : public std::vector<Type>
00038 {
00039  public:
00040   RWLockVector();
00041   RWLockVector(const RWLockVector<Type> &lv);
00042   virtual ~RWLockVector();
00043   virtual void  lock_for_read() const;
00044   virtual void  lock_for_write() const;
00045   virtual bool  try_lock_for_read() const;
00046   virtual bool  try_lock_for_write() const;
00047   virtual void  unlock() const;
00048   RefPtr<ReadWriteLock> rwlock() const;
00049 
00050   void     push_back_locked(const Type& x);
00051   void     pop_back_locked();
00052   void     erase_locked(typename std::vector<Type>::iterator pos);
00053   void     erase_locked(typename std::vector<Type>::iterator first,
00054                         typename std::vector<Type>::iterator last);
00055 
00056   RWLockVector<Type> &  operator=(const RWLockVector<Type> &lv);
00057   RWLockVector<Type> &  operator=(const std::vector<Type> &v);
00058  private:
00059   mutable RefPtr<ReadWriteLock> __rwlock;
00060 
00061 };
00062 
00063 
00064 /** @class RWLockVector <core/utils/rwlock_vector.h>
00065  * Vector with a lock.
00066  * This class provides a vector that has an intrinsic lock. The lock can be applied
00067  * with the regular locking methods.
00068  *
00069  * @see ReadWriteLock
00070  * @ingroup FCL
00071  * @author Tim Niemueller
00072  */
00073 
00074 
00075 /** Constructor. */
00076 template <typename Type>
00077 RWLockVector<Type>::RWLockVector()
00078   : __rwlock(new ReadWriteLock())
00079 {}
00080 
00081 
00082 /** Copy constructor.
00083  * @param lv RWLockVector to copy
00084  */
00085 template <typename Type>
00086 RWLockVector<Type>::RWLockVector(const RWLockVector<Type> &lv)
00087   : std::vector<Type>::vector(lv), __rwlock(new ReadWriteLock())
00088 {}
00089 
00090 
00091 /** Destructor. */
00092 template <typename Type>
00093 RWLockVector<Type>::~RWLockVector()
00094 {}
00095 
00096 
00097 /** Lock vector for reading. */
00098 template <typename Type>
00099 void
00100 RWLockVector<Type>::lock_for_read() const
00101 {
00102   __rwlock->lock_for_read();
00103 }
00104 
00105 
00106 /** Lock vector for writing. */
00107 template <typename Type>
00108 void
00109 RWLockVector<Type>::lock_for_write() const
00110 {
00111   __rwlock->lock_for_write();
00112 }
00113 
00114 
00115 /** Try to lock vector for reading.
00116  * @return true, if the lock has been aquired, false otherwise.
00117  */
00118 template <typename Type>
00119 bool
00120 RWLockVector<Type>::try_lock_for_read() const
00121 {
00122   return __rwlock->try_lock_for_read();
00123 }
00124 
00125 
00126 /** Try to lock vector for writing.
00127  * @return true, if the lock has been aquired, false otherwise.
00128  */
00129 template <typename Type>
00130 bool
00131 RWLockVector<Type>::try_lock_for_write() const
00132 {
00133   return __rwlock->try_lock_for_write();
00134 }
00135 
00136 
00137 /** Unlock vector. */
00138 template <typename Type>
00139 void
00140 RWLockVector<Type>::unlock() const
00141 {
00142   return __rwlock->unlock();
00143 }
00144 
00145 
00146 /** Push element to vector at back with lock protection.
00147  * @param x element to add
00148  */
00149 template <typename Type>
00150 void
00151 RWLockVector<Type>::push_back_locked(const Type& x)
00152 {
00153   __rwlock->lock_for_write();
00154   std::vector<Type>::push_back(x);
00155   __rwlock->unlock();
00156 }
00157 
00158 
00159 /** Remove last element with lock protection. */
00160 template <typename Type>
00161 void
00162 RWLockVector<Type>::pop_back_locked()
00163 {
00164   __rwlock->lock_for_write();
00165   std::vector<Type>::pop_back();
00166   __rwlock->unlock();
00167 }
00168 
00169 
00170 /** Erase given element with lock protection.
00171  * @param pos iterator for the object position to remove
00172  */
00173 template <typename Type>
00174 void
00175 RWLockVector<Type>::erase_locked(typename std::vector<Type>::iterator pos)
00176 {
00177   __rwlock->lock_for_write();
00178   std::vector<Type>::erase(pos);
00179   __rwlock->unlock();
00180 }
00181 
00182 /** Erase given element range with lock protection.
00183  * @param first iterator to first element to erase
00184  * @param last iterator to first element not to erase
00185  */
00186 template <typename Type>
00187 void
00188 RWLockVector<Type>::erase_locked(typename std::vector<Type>::iterator first,
00189                                typename std::vector<Type>::iterator last)
00190 {
00191   __rwlock->lock_for_write();
00192   std::vector<Type>::erase(first, last);
00193   __rwlock->unlock();
00194 }
00195 
00196 
00197 /** Get access to the internal read/write lock.
00198  * @return internal read/write lock
00199  */
00200 template <typename Type>
00201 RefPtr<ReadWriteLock>
00202 RWLockVector<Type>::rwlock() const
00203 {
00204   return __rwlock;
00205 }
00206 
00207 
00208 /** Copy values from another RWLockVector.
00209  * Copies the values one by one. Both instances are locked during the copying and
00210  * this instance is cleared before copying.
00211  * @param lv vector to copy
00212  * @return reference to this instance
00213  */
00214 template <typename Type>
00215 RWLockVector<Type> &
00216 RWLockVector<Type>::operator=(const RWLockVector<Type> &lv)
00217 {
00218   __rwlock->lock_for_write();
00219   lv.lock_for_read();
00220   this->clear();
00221   typename RWLockVector<Type>::const_iterator i;
00222   for (i = lv.begin(); i != lv.end(); ++i) {
00223     this->push_back(*i);
00224   }
00225   lv.unlock();
00226   __rwlock->unlock();
00227 
00228   return *this;
00229 }
00230 
00231 
00232 /** Copy values from a standard vector.
00233  * Copies the values one by one. This instance is locked during the copying and
00234  * cleared.
00235  * @param v vector to copy
00236  * @return reference to this instance
00237  */
00238 template <typename Type>
00239 RWLockVector<Type> &
00240 RWLockVector<Type>::operator=(const std::vector<Type> &v)
00241 {
00242   __rwlock->lock_for_write();
00243   this->clear();
00244   typename std::vector<Type>::const_iterator i;
00245   for (i = v.begin(); i != v.end(); ++i) {
00246     this->push_back(*i);
00247   }
00248   __rwlock->unlock();
00249 
00250   return *this;
00251 }
00252 
00253 } // end namespace fawkes
00254 
00255 #endif