Fawkes API Fawkes Development Version
|
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