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