Fawkes API  Fawkes Development Version
rwlock_queue.h
00001 
00002 /***************************************************************************
00003  *  rwlock_queue.h - Queue with read/write lock
00004  *
00005  *  Created: Tue Jan 13 16:36:52 2009
00006  *  Copyright  2006-2009  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_QUEUE_H_
00025 #define __CORE_UTILS_RWLOCK_QUEUE_H_
00026 
00027 #include <core/threading/read_write_lock.h>
00028 #include <core/utils/refptr.h>
00029 #include <queue>
00030 
00031 namespace fawkes {
00032 
00033 
00034 template <typename Type>
00035 class RWLockQueue : public std::queue<Type>
00036 {
00037  public:
00038   RWLockQueue();
00039   RWLockQueue(const RWLockQueue<Type> &ll);
00040   virtual ~RWLockQueue();
00041 
00042   void                   lock_for_read();
00043   void                   lock_for_write();
00044   bool                   try_lock_for_read();
00045   bool                   try_lock_for_write();
00046   void                   unlock();
00047   RefPtr<ReadWriteLock>  rwlock() const;
00048 
00049   void     push_locked(const Type& x);
00050   void     pop_locked();
00051 
00052   void clear();
00053 
00054   // not needed, no change to rwlock required (thus "incomplete" BigThree)
00055   //LockList<Type> &  operator=(const LockList<Type> &ll);
00056  private:
00057   RefPtr<ReadWriteLock> __rwlock;
00058 
00059 };
00060 
00061 
00062 /** @class RWLockQueue <core/utils/rwlock_queue.h>
00063  * Queue with a read/write lock.
00064  * This class provides a queue that has an intrinsic lock. The lock can be applied
00065  * with the regular locking methods.
00066  *
00067  * @see ReadWriteLock
00068  * @ingroup FCL
00069  * @author Tim Niemueller
00070  */
00071 
00072 
00073 /** Constructor. */
00074 template <typename Type>
00075 RWLockQueue<Type>::RWLockQueue()
00076 {
00077   __rwlock = new ReadWriteLock();
00078 }
00079 
00080 
00081 /** Copy constructor.
00082  * @param ll RWLockQueue to copy
00083  */
00084 template <typename Type>
00085 RWLockQueue<Type>::RWLockQueue(const RWLockQueue<Type> &ll)
00086   : std::queue<Type>::queue(ll)
00087 {
00088   __rwlock = new ReadWriteLock();
00089 }
00090 
00091 
00092 /** Destructor. */
00093 template <typename Type>
00094 RWLockQueue<Type>::~RWLockQueue()
00095 {
00096   delete __rwlock;
00097 }
00098 
00099 
00100 /** Lock queue for reading. */
00101 template <typename Type>
00102 void
00103 RWLockQueue<Type>::lock_for_read()
00104 {
00105   __rwlock->lock_for_read();
00106 }
00107 
00108 
00109 /** Lock queue for writing. */
00110 template <typename Type>
00111 void
00112 RWLockQueue<Type>::lock_for_write()
00113 {
00114   __rwlock->lock_for_write();
00115 }
00116 
00117 
00118 /** Try to lock queue for reading.
00119  * @return true, if the lock has been aquired, false otherwise.
00120  */
00121 template <typename Type>
00122 bool
00123 RWLockQueue<Type>::try_lock_for_read()
00124 {
00125   return __rwlock->try_lock_for_read();
00126 }
00127 
00128 
00129 /** Try to lock queue for writing.
00130  * @return true, if the lock has been aquired, false otherwise.
00131  */
00132 template <typename Type>
00133 bool
00134 RWLockQueue<Type>::try_lock_for_write()
00135 {
00136   return __rwlock->try_lock_for_write();
00137 }
00138 
00139 
00140 /** Unlock list. */
00141 template <typename Type>
00142 void
00143 RWLockQueue<Type>::unlock()
00144 {
00145   return __rwlock->unlock();
00146 }
00147 
00148 
00149 /** Push element to queue with lock protection.
00150  * @param x element to add
00151  */
00152 template <typename Type>
00153 void
00154 RWLockQueue<Type>::push_locked(const Type& x)
00155 {
00156   __rwlock->lock_for_write();
00157   std::queue<Type>::push(x);
00158   __rwlock->unlock();
00159 }
00160 
00161 
00162 /** Pop element from queue with lock protection.
00163  */
00164 template <typename Type>
00165 void
00166 RWLockQueue<Type>::pop_locked()
00167 {
00168   __rwlock->lock_for_write();
00169   std::queue<Type>::pop();
00170   __rwlock->unlock();
00171 }
00172 
00173 
00174 /** Clear the queue. */
00175 template <typename Type>
00176 void
00177 RWLockQueue<Type>::clear()
00178 {
00179   __rwlock->lock_for_write();
00180   while ( ! std::queue<Type>::empty() ) {
00181     std::queue<Type>::pop();
00182   }
00183   __rwlock->unlock();
00184 }
00185 
00186 
00187 /** Get access to the internal rwlock.
00188  * Can be used with RwlockLocker.
00189  * @return internal rwlock
00190  */
00191 template <typename Type>
00192 ReadWriteLock *
00193 RWLockQueue<Type>::rwlock() const
00194 {
00195   return __rwlock;
00196 }
00197 
00198 
00199 } // end namespace fawkes
00200 
00201 #endif