diff --git a/MITLib/Utility/ConcurrentQueue.h b/MITLib/Utility/ConcurrentQueue.h index 1b0e5fd..e9469ce 100644 --- a/MITLib/Utility/ConcurrentQueue.h +++ b/MITLib/Utility/ConcurrentQueue.h @@ -66,6 +66,50 @@ public: return true; } + // Pushes object T when space is available + // Throws std::exception on timeout or when interrupted + bool PushFront(T item, int milliSeconds = INFINITE) { + bool bPushedItem = false; + CSingleLock lock(&m_mutex); + while(!bPushedItem) { + try + { + // Wait for space to be available + m_spaceAvailableEvent.WaitEvtEx(milliSeconds); + } catch(std::exception &e) { + printf("Push failed: %s\n", e.what()); + throw; + } + + // wait for critical section to become available + lock.Lock(); + + // inside critical section + { + size_t size = m_queue.size(); + // Make sure that nobody else that was waiting pushed first + if( size < m_capacity) { + m_queue.push_front(item); + bPushedItem = true; + + if (size == 0) + { + // Queue was empty, now there is one item + m_dataAvailableEvent.Set(); + } + + size++; + if (size >= m_capacity) { + // Queue is now full + m_spaceAvailableEvent.Reset(); + } + } + } + lock.Unlock(); + } + return true; + } + // Returns object T when available // Throws std::exception on timeout or when interrupted T Pop(int milliSeconds = INFINITE) @@ -114,9 +158,9 @@ private: // wait for event to be signaled that there is data if (bThrowException) { - m_dataAvailableEvent.WaitEvtEx(milliSeconds); + m_dataAvailableEvent.WaitEvtEx(remaining); } - else if (!m_dataAvailableEvent.WaitEvt(milliSeconds)) + else if (!m_dataAvailableEvent.WaitEvt(remaining)) { return false; }