Fawkes API  Fawkes Development Version
lock_vector.h
00001 
00002 /***************************************************************************
00003  *  lock_vector.h - Lockable vector
00004  *
00005  *  Created: Mon Jan 10 11:11:59 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_LOCK_VECTOR_H_
00025 #define __CORE_UTILS_LOCK_VECTOR_H_
00026 
00027 #include <core/threading/mutex.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 LockVector : public std::vector<Type>
00038 {
00039  public:
00040   LockVector();
00041   LockVector(const LockVector<Type> &lv);
00042   virtual ~LockVector();
00043   virtual void  lock() const;
00044   virtual bool  try_lock() const;
00045   virtual void  unlock() const;
00046   RefPtr<Mutex> mutex() const;
00047 
00048   void     push_back_locked(const Type& x);
00049   void     pop_back_locked();
00050   void     erase_locked(typename std::vector<Type>::iterator pos);
00051   void     erase_locked(typename std::vector<Type>::iterator first,
00052                         typename std::vector<Type>::iterator last);
00053 
00054   LockVector<Type> &  operator=(const LockVector<Type> &lv);
00055   LockVector<Type> &  operator=(const std::vector<Type> &v);
00056  private:
00057   mutable RefPtr<Mutex> __mutex;
00058 
00059 };
00060 
00061 
00062 /** @class LockVector <core/utils/lock_vector.h>
00063  * Vector with a lock.
00064  * This class provides a vector that has an intrinsic lock. The lock can be applied
00065  * with the regular locking methods.
00066  *
00067  * @see Mutex
00068  * @ingroup FCL
00069  * @author Tim Niemueller
00070  */
00071 
00072 
00073 /** Constructor. */
00074 template <typename Type>
00075 LockVector<Type>::LockVector()
00076   : __mutex(new Mutex())
00077 {}
00078 
00079 
00080 /** Copy constructor.
00081  * @param lv LockVector to copy
00082  */
00083 template <typename Type>
00084 LockVector<Type>::LockVector(const LockVector<Type> &lv)
00085   : std::vector<Type>::vector(lv), __mutex(new Mutex())
00086 {}
00087 
00088 
00089 /** Destructor. */
00090 template <typename Type>
00091 LockVector<Type>::~LockVector()
00092 {}
00093 
00094 
00095 /** Lock vector. */
00096 template <typename Type>
00097 void
00098 LockVector<Type>::lock() const
00099 {
00100   __mutex->lock();
00101 }
00102 
00103 
00104 /** Try to lock vector.
00105  * @return true, if the lock has been aquired, false otherwise.
00106  */
00107 template <typename Type>
00108 bool
00109 LockVector<Type>::try_lock() const
00110 {
00111   return __mutex->try_lock();
00112 }
00113 
00114 
00115 /** Unlock vector. */
00116 template <typename Type>
00117 void
00118 LockVector<Type>::unlock() const
00119 {
00120   return __mutex->unlock();
00121 }
00122 
00123 
00124 /** Push element to vector at back with lock protection.
00125  * @param x element to add
00126  */
00127 template <typename Type>
00128 void
00129 LockVector<Type>::push_back_locked(const Type& x)
00130 {
00131   __mutex->lock();
00132   std::vector<Type>::push_back(x);
00133   __mutex->unlock();
00134 }
00135 
00136 
00137 /** Remove last element with lock protection. */
00138 template <typename Type>
00139 void
00140 LockVector<Type>::pop_back_locked()
00141 {
00142   __mutex->lock();
00143   std::vector<Type>::pop_back();
00144   __mutex->unlock();
00145 }
00146 
00147 
00148 /** Erase given element with lock protection.
00149  * @param pos iterator for the object position to remove
00150  */
00151 template <typename Type>
00152 void
00153 LockVector<Type>::erase_locked(typename std::vector<Type>::iterator pos)
00154 {
00155   __mutex->lock();
00156   std::vector<Type>::erase(pos);
00157   __mutex->unlock();
00158 }
00159 
00160 /** Erase given element range with lock protection.
00161  * @param first iterator to first element to erase
00162  * @param last iterator to first element not to erase
00163  */
00164 template <typename Type>
00165 void
00166 LockVector<Type>::erase_locked(typename std::vector<Type>::iterator first,
00167                                typename std::vector<Type>::iterator last)
00168 {
00169   __mutex->lock();
00170   std::vector<Type>::erase(first, last);
00171   __mutex->unlock();
00172 }
00173 
00174 
00175 /** Get access to the internal mutex.
00176  * Can be used with MutexLocker.
00177  * @return internal mutex
00178  */
00179 template <typename Type>
00180 RefPtr<Mutex>
00181 LockVector<Type>::mutex() const
00182 {
00183   return __mutex;
00184 }
00185 
00186 
00187 /** Copy values from another LockVector.
00188  * Copies the values one by one. Both instances are locked during the copying and
00189  * this instance is cleared before copying.
00190  * @param lv vector to copy
00191  * @return reference to this instance
00192  */
00193 template <typename Type>
00194 LockVector<Type> &
00195 LockVector<Type>::operator=(const LockVector<Type> &lv)
00196 {
00197   __mutex->lock();
00198   lv.lock();
00199   this->clear();
00200   typename LockVector<Type>::const_iterator i;
00201   for (i = lv.begin(); i != lv.end(); ++i) {
00202     this->push_back(*i);
00203   }
00204   lv.unlock();
00205   __mutex->unlock();
00206 
00207   return *this;
00208 }
00209 
00210 
00211 /** Copy values from a standard vector.
00212  * Copies the values one by one. This instance is locked during the copying and
00213  * cleared.
00214  * @param v vector to copy
00215  * @return reference to this instance
00216  */
00217 template <typename Type>
00218 LockVector<Type> &
00219 LockVector<Type>::operator=(const std::vector<Type> &v)
00220 {
00221   __mutex->lock();
00222   this->clear();
00223   typename std::vector<Type>::const_iterator i;
00224   for (i = v.begin(); i != v.end(); ++i) {
00225     this->push_back(*i);
00226   }
00227   __mutex->unlock();
00228 
00229   return *this;
00230 }
00231 
00232 } // end namespace fawkes
00233 
00234 #endif