00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #ifndef OW32_circularbuffer_h
00023 #define OW32_circularbuffer_h
00024
00025 #include <OW32/SyncObjects.h>
00026 #include <cstddef>
00027
00033 namespace OW32
00034 {
00035
00037 template <class T>
00038 class CCircularBuffer
00039 {
00040 public:
00053 CCircularBuffer(size_t queueSize) :
00054 m_head(0),
00055 m_tail(0),
00056 m_semEmpty(static_cast<LONG>(queueSize), static_cast<LONG>(queueSize)),
00057 m_semFull(static_cast<LONG>(queueSize), 0L),
00058 m_evBreak(TRUE),
00059 m_fBreak(false),
00060 m_queueSize(queueSize)
00061 {
00062 m_buf = new T[m_queueSize];
00063 }
00064
00066 ~CCircularBuffer()
00067 {
00068 delete [] m_buf;
00069 }
00070
00072 bool isBroken()
00073 {
00074 return m_fBreak;
00075 }
00076
00085 void Break()
00086 {
00087 m_fBreak = true;
00088 m_evBreak.Set();
00089 }
00090
00096 void ResetBreak()
00097 {
00098 m_fBreak = false;
00099 m_evBreak.Reset();
00100 }
00101
00111 bool putElement(const T& el, DWORD nTimeout = INFINITE)
00112 {
00113
00114 HANDLE wait_space[2] = { m_semEmpty, m_evBreak };
00115
00116 switch (WaitForMultipleObjects(2, wait_space, FALSE, nTimeout)) {
00117 case WAIT_OBJECT_0:
00118 if (m_fBreak)
00119 return false;
00120 break;
00121 case WAIT_TIMEOUT:
00122 return false;
00123 default:
00124 return false;
00125 }
00126
00127
00128 {
00129 CSingleLock access_tail(m_csTail);
00130 m_buf[m_tail] = el;
00131 m_tail = (m_tail+1)%m_queueSize;
00132 }
00133
00134
00135 m_semFull.Release(1);
00136 return true;
00137 }
00138
00148 bool getElement(T& el, DWORD nTimeout = INFINITE)
00149 {
00150
00151 HANDLE wait_space[2] = { m_semFull, m_evBreak };
00152
00153 switch (WaitForMultipleObjects(2, wait_space, FALSE, nTimeout)) {
00154 case WAIT_OBJECT_0:
00155 if (m_fBreak)
00156 return false;
00157 break;
00158 case WAIT_TIMEOUT:
00159 return false;
00160 default:
00161 return false;
00162 }
00163
00164
00165 {
00166 CSingleLock access_head(m_csHead);
00167 el = m_buf[m_head];
00168 m_head = (m_head+1)%m_queueSize;
00169 }
00170
00171
00172 m_semEmpty.Release(1);
00173 return true;
00174 }
00175
00176 private:
00177 size_t m_head, m_tail, m_queueSize;
00178 T* m_buf;
00179 CSemaphore m_semEmpty, m_semFull;
00180 CCriticalSection m_csHead, m_csTail;
00181
00182
00183 CEvent m_evBreak;
00184 bool m_fBreak;
00185
00186
00187 CCircularBuffer& operator=(const CCircularBuffer&);
00188 CCircularBuffer(const CCircularBuffer&);
00189
00190 };
00191
00192 };
00193
00194 #endif // OW32_circularbuffer_h