1
0
Fork 0
cuberite-2a/src/OSSupport/Queue.h

103 lines
2.0 KiB
C
Raw Normal View History

2013-12-21 14:43:32 +00:00
#pragma once
#include <list>
//this empty struct allows function inlining
2013-12-21 14:43:32 +00:00
template<class T>
struct cQueueFuncs
2013-12-21 14:43:32 +00:00
{
public:
static void Delete(T) {};
static void Combine(T&, const T) {};
};
2013-12-21 14:43:32 +00:00
template<class ItemType, class Funcs = cQueueFuncs<ItemType> >
2013-12-21 14:43:32 +00:00
class cQueue
{
typedef typename std::list<ItemType> ListType;
//magic typedef to persuade clang that the iterator is a type
typedef typename ListType::iterator iterator;
2013-12-21 14:43:32 +00:00
public:
cQueue() {}
~cQueue() {}
void EnqueueItem(ItemType a_item)
{
cCSLock Lock(m_CS);
m_contents.push_back(a_item);
m_evtAdded.Set();
}
void EnqueueItemIfNotPresent(ItemType a_item)
{
cCSLock Lock(m_CS);
for (iterator itr = m_contents.begin(); itr != m_contents.end(); ++itr)
{
if((*itr) == a_item) {
Funcs funcTable;
funcTable.Combine(*itr,a_item);
return;
}
}
m_contents.push_back(a_item);
m_evtAdded.Set();
}
bool TryDequeueItem(ItemType& item)
{
cCSLock Lock(m_CS);
if (m_contents.size() == 0) return false;
item = m_contents.front();
m_contents.pop_front();
m_evtRemoved.Set();
return true;
}
ItemType DequeueItem()
{
cCSLock Lock(m_CS);
while (m_contents.size() == 0)
{
cCSUnlock Unlock(m_CS);
m_evtAdded.Wait();
}
ItemType item = m_contents.front();
m_contents.pop_front();
m_evtRemoved.Set();
return item;
}
void BlockTillEmpty() {
//There is a very slight race condition here if the load completes between the check
//and the wait.
while(!(Size() == 0)){m_evtRemoved.Wait();}
}
//can all be inlined when delete is a noop
void Clear()
{
cCSLock Lock(m_CS);
Funcs funcTable;
while (!m_contents.empty())
{
funcTable.Delete(m_contents.front());
m_contents.pop_front();
}
}
size_t Size()
{
cCSLock Lock(m_CS);
return m_contents.size();
}
bool Remove(ItemType item)
{
cCSLock Lock(m_CS);
m_contents.remove(item);
m_evtRemoved.Set();
}
2013-12-21 14:43:32 +00:00
private:
ListType m_contents;
cCriticalSection m_CS;
cEvent m_evtAdded;
cEvent m_evtRemoved;
};