summaryrefslogtreecommitdiffstats
path: root/src/OSSupport
diff options
context:
space:
mode:
Diffstat (limited to 'src/OSSupport')
-rw-r--r--src/OSSupport/Promise.cpp54
-rw-r--r--src/OSSupport/Promise.h38
-rw-r--r--src/OSSupport/Queue.h109
3 files changed, 183 insertions, 18 deletions
diff --git a/src/OSSupport/Promise.cpp b/src/OSSupport/Promise.cpp
new file mode 100644
index 000000000..b31869334
--- /dev/null
+++ b/src/OSSupport/Promise.cpp
@@ -0,0 +1,54 @@
+
+#include "Globals.h"
+
+#include "Promise.h"
+
+cPromise * cPromise::WaitFor(cPromise * a_Promise)
+{
+ return new cCombinedPromise(this, a_Promise);
+}
+
+cPromise * cPromise::CancelOn(volatile bool& cancelation)
+{
+ return new cCancelablePromise(this, cancelation);
+}
+
+void cPromise::Wait()
+{
+ while(!IsCompleted()){}; //busywait best we can do until waitany
+}
+
+
+cCombinedPromise::cCombinedPromise(cPromise* a_left, cPromise* a_right) :
+ cPromise(),
+ m_left(a_left),
+ m_right(a_right)
+{
+}
+
+cCombinedPromise::~cCombinedPromise()
+{
+}
+
+bool cCombinedPromise::IsCompleted()
+{
+ return m_left->IsCompleted() || m_right->IsCompleted();
+}
+
+cCancelablePromise::cCancelablePromise(cPromise* a_wrapped, volatile bool& a_cancel) :
+ cPromise(),
+ m_cancel(a_cancel),
+ m_wrapped(a_wrapped)
+{
+}
+
+cCancelablePromise::~cCancelablePromise ()
+{
+}
+
+bool cCancelablePromise::IsCompleted()
+{
+ return m_cancel || m_wrapped->IsCompleted();
+}
+
+
diff --git a/src/OSSupport/Promise.h b/src/OSSupport/Promise.h
new file mode 100644
index 000000000..83d04860b
--- /dev/null
+++ b/src/OSSupport/Promise.h
@@ -0,0 +1,38 @@
+#pragma once
+
+class cCombinedPromise;
+
+
+class cPromise {
+ public:
+ cPromise() {}
+ virtual ~cPromise () {}
+ cPromise * WaitFor(cPromise * a_Promise);
+ cPromise * CancelOn(volatile bool& cancelationtoken);
+ void Wait();
+ virtual bool IsCompleted() = 0;
+ //TODO:Expose Events for waiting on
+};
+
+class cCombinedPromise : public cPromise {
+public:
+ cCombinedPromise(cPromise*, cPromise*);
+ ~cCombinedPromise();
+ virtual bool IsCompleted();
+private:
+ cPromise* m_left;
+ cPromise* m_right;
+};
+
+class cCancelablePromise : public cPromise {
+public:
+ cCancelablePromise(cPromise*, volatile bool&);
+ ~cCancelablePromise();
+ virtual bool IsCompleted();
+private:
+ volatile bool& m_cancel;
+ cPromise* m_wrapped;
+};
+
+
+
diff --git a/src/OSSupport/Queue.h b/src/OSSupport/Queue.h
index 4571272b3..eb323b067 100644
--- a/src/OSSupport/Queue.h
+++ b/src/OSSupport/Queue.h
@@ -1,31 +1,104 @@
+
#pragma once
+#include <list>
+
+#include "../OSSupport/Promise.h"
+
+//this empty struct allows function inlining
template<class T>
-class cDeleter
+struct cQueueFuncs
{
public:
static void Delete(T) {};
+ static void Combine(T&, const T) {};
};
-template<class T, class D = cDeleter<T>>
+template<class ItemType, class Funcs = cQueueFuncs<ItemType> >
class cQueue
{
+
+typedef typename std::list<ItemType> ListType;
+//magic typedef to persuade clang that the iterator is a type
+typedef typename ListType::iterator iterator;
public:
- cQueue(int warnsize);
- cQueue(cQueue<T>& queue);
- ~cQueue();
-
- void EnqueueItem(T item);
- bool TryDequeueItem(T& item);
- T DequeueItem();
- void BlockTillEmpty(cEvent CancelationEvent);
- void Clear();
- int Size();
-
+ 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();
+ return true;
+ }
+ ItemType DequeueItem()
+ {
+ cCSLock Lock(m_CS);
+ while (m_contents.size() == 0)
+ {
+ cCSUnlock Unlock(m_CS);
+ m_evtAdded.Wait();
+ }
+ return m_contents.pop_front();
+ }
+ cPromise* BlockTillEmpty() {
+ return new cEmptyQueuePromise(this);
+ }
+ //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);
+ }
+
private:
- int warnsize;
- std::list<T> contents;
-};
+ ListType m_contents;
+ cCriticalSection m_CS;
+ cEvent m_evtAdded;
-//template classes must be implemented in the header
-#include "Queue.inc"
+ class cEmptyQueuePromise : public cPromise {
+ public:
+ cEmptyQueuePromise(cQueue* a_Queue) : cPromise(), m_Queue(a_Queue) {}
+ virtual bool IsCompleted() {return m_Queue->Size() != 0;}
+ private:
+ cQueue* m_Queue;
+ };
+};