00001 /***************************************************************************** 00002 * Copyright (C) 2011 by Benjamin Hadorn (b_hadorn@bluewin.ch) 00003 ***************************************************************************** 00004 * Project : Zeus Base Library 00005 * Module : AtomicQueue 00006 * Package : Zeus.ZeusBase.System 00007 * Author : Benjamin Hadorn 00008 * Date : 27.12.2011 00009 * System : Zeus-Framework 00010 ***************************************************************************** 00011 * Licence: * 00012 * This library is free software; you can redistribute it and/or modify * 00013 * it under the terms of the GNU Lesser General Public License as * 00014 * published by the Free Software Foundation; either version * 00015 * 2.1 of the License, or (at your option) any later version. * 00016 * * 00017 * This library is distributed in the hope that it will be useful, * 00018 * but WITHOUT ANY WARRANTY; without even the implied warranty of * 00019 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 00020 * GNU Lesser General Public License for more details. * 00021 * * 00022 * You should have received a copy of the GNU Lesser General Public * 00023 * License along with this library; if not, write to the Free Software * 00024 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110, USA * 00025 *****************************************************************************/ 00026 00027 /***************************************************************************** 00028 * Changes: 00029 * 27.12.2011 bha: created zeus 2.0 00030 *****************************************************************************/ 00031 00032 #ifndef AtomicQueueHPP 00033 #define AtomicQueueHPP 00034 00035 #include <zeusbase/System/CriticalSection.h> 00036 #include <zeusbase/System/CriticalScopeLock.hpp> 00037 #include <zeusbase/System/Queue.hpp> 00038 00039 BEGIN_NAMESPACE_Zeus 00040 00041 /******************************************************************************/ 00044 /******************************************************************************/ 00045 template <class T> class TAtomicQueue : public IQueue<T> 00046 { 00047 public: 00048 TAtomicQueue(); 00049 TAtomicQueue(TAtomicQueue<T>& rQueue); 00050 TAtomicQueue(IQueue<T>& rQueue); 00051 TAtomicQueue(const T& rEmptyObject); 00052 virtual ~TAtomicQueue(); 00053 00054 //Methods of IQueue 00055 virtual void MQUALIFIER appendItem(const T& tData); 00056 virtual void MQUALIFIER copyToQueue(IQueue<T>& rQueue) const; 00057 virtual void MQUALIFIER copyToList(IList<T>& rList) const; 00058 virtual T MQUALIFIER removeItem(); 00059 virtual Int MQUALIFIER getCount() const; 00060 virtual void MQUALIFIER flush(); 00061 virtual bool MQUALIFIER isEmpty() const; 00062 virtual T& MQUALIFIER peekItem() ; 00063 virtual const T& MQUALIFIER peekItemConst() const; 00064 00065 //operators 00066 TAtomicQueue<T>& operator=(const TAtomicQueue<T>& rQueue); 00067 TAtomicQueue<T>& operator=(const TQueue<T>& rQueue); 00068 TAtomicQueue<T>& operator=(const IQueue<T>& rQueue); 00069 00070 private: 00072 TQueue<T> m_queueData; 00074 TCriticalSection& m_rLock; 00075 }; 00076 00077 00078 /******************************************************************************/ 00081 /******************************************************************************/ 00082 template <class T> inline TAtomicQueue<T>::TAtomicQueue() 00083 : m_rLock(*new TCriticalSection(TCriticalSection::etRecursive)) 00084 {} 00085 00086 /******************************************************************************/ 00089 /******************************************************************************/ 00090 template <class T> inline TAtomicQueue<T>::TAtomicQueue(IQueue<T>& rQueue) 00091 : m_rLock(*new TCriticalSection(TCriticalSection::etRecursive)), 00092 m_queueData(rQueue) 00093 {} 00094 00095 /******************************************************************************/ 00098 /******************************************************************************/ 00099 template <class T> inline TAtomicQueue<T>::TAtomicQueue(TAtomicQueue<T>& rQueue) 00100 : m_rLock(*new TCriticalSection(TCriticalSection::etRecursive)) 00101 { 00102 *this = rQueue; 00103 } 00104 00105 /******************************************************************************/ 00108 /******************************************************************************/ 00109 template <class T> inline TAtomicQueue<T>::TAtomicQueue(const T& rEmptyObject) 00110 : m_rLock(*new TCriticalSection(TCriticalSection::etRecursive)), 00111 m_queueData(rEmptyObject) 00112 {} 00113 00114 /******************************************************************************/ 00117 /******************************************************************************/ 00118 template <class T> inline TAtomicQueue<T>::~TAtomicQueue() 00119 { 00120 m_rLock.release(); 00121 } 00122 00123 /******************************************************************************/ 00126 /******************************************************************************/ 00127 template <class T> inline void MQUALIFIER TAtomicQueue<T>::appendItem(const T& tData) 00128 { 00130 // LOCK 00131 TCriticalScopeLock Lock(m_rLock); 00132 m_queueData.appendItem(tData); 00134 } 00135 00136 /******************************************************************************/ 00139 /******************************************************************************/ 00140 template <class T> inline void MQUALIFIER TAtomicQueue<T>::copyToQueue(IQueue<T>& rQueue) const 00141 { 00143 // LOCK 00144 TCriticalScopeLock Lock(m_rLock); 00145 m_queueData.copyToQueue(rQueue); 00147 } 00148 00149 /******************************************************************************/ 00152 /******************************************************************************/ 00153 template <class T> inline void MQUALIFIER TAtomicQueue<T>::copyToList(IList<T>& rList) const 00154 { 00156 // LOCK 00157 TCriticalScopeLock Lock(m_rLock); 00158 m_queueData.copyToList(rList); 00160 } 00161 00162 /******************************************************************************/ 00165 /******************************************************************************/ 00166 template <class T> inline T MQUALIFIER TAtomicQueue<T>::removeItem() 00167 { 00169 // LOCK 00170 TCriticalScopeLock Lock(m_rLock); 00171 return m_queueData.removeItem(); 00173 } 00174 00175 /******************************************************************************/ 00178 /******************************************************************************/ 00179 template <class T> inline Int MQUALIFIER TAtomicQueue<T>::getCount() const 00180 { 00182 // LOCK 00183 TCriticalScopeLock Lock(m_rLock); 00184 return m_queueData.getCount(); 00186 } 00187 00188 00189 /******************************************************************************/ 00192 /******************************************************************************/ 00193 template <class T> inline void MQUALIFIER TAtomicQueue<T>::flush() 00194 { 00196 // LOCK 00197 TCriticalScopeLock Lock(m_rLock); 00198 m_queueData.flush(); 00200 } 00201 00202 /******************************************************************************/ 00205 /******************************************************************************/ 00206 template <class T> inline bool MQUALIFIER TAtomicQueue<T>::isEmpty() const 00207 { 00209 // LOCK 00210 TCriticalScopeLock Lock(m_rLock); 00211 return m_queueData.isEmpty(); 00213 } 00214 00215 /******************************************************************************/ 00218 /******************************************************************************/ 00219 template <class T> inline T& MQUALIFIER TAtomicQueue<T>::peekItem() 00220 { 00222 // LOCK 00223 TCriticalScopeLock Lock(m_rLock); 00224 return m_queueData.peekItem(); 00226 } 00227 00228 /******************************************************************************/ 00231 /******************************************************************************/ 00232 template <class T> inline const T& MQUALIFIER TAtomicQueue<T>::peekItemConst() const 00233 { 00235 // LOCK 00236 TCriticalScopeLock Lock(m_rLock); 00237 return m_queueData.peekItemConst(); 00239 } 00240 00241 /******************************************************************************/ 00245 /******************************************************************************/ 00246 template <class T> inline TAtomicQueue<T>& TAtomicQueue<T>::operator=(const TAtomicQueue<T>& rQueue) 00247 { 00249 // LOCK 00250 m_rLock.enter(); 00251 rQueue.m_rLock.enter(); 00252 00253 m_queueData = rQueue.m_queueData; 00254 00255 rQueue.m_rLock.leave(); 00256 m_rLock.leave(); 00258 00259 return *this; 00260 } 00261 00262 /******************************************************************************/ 00266 /******************************************************************************/ 00267 template <class T> inline TAtomicQueue<T>& TAtomicQueue<T>::operator=(const TQueue<T>& rQueue) 00268 { 00270 // LOCK 00271 TCriticalScopeLock Lock(m_rLock); 00272 m_queueData = rQueue; 00273 return *this; 00275 } 00276 00277 /******************************************************************************/ 00281 /******************************************************************************/ 00282 template <class T> inline TAtomicQueue<T>& TAtomicQueue<T>::operator=(const IQueue<T>& rQueue) 00283 { 00285 // LOCK 00286 TCriticalScopeLock Lock(m_rLock); 00287 m_queueData = rQueue; 00288 return *this; 00290 } 00291 00292 END_NAMESPACE_Zeus 00293 00294 00295 #endif