summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorTycho Bickerstaff <work.tycho@gmail.com>2014-01-02 13:32:55 +0100
committerTycho Bickerstaff <work.tycho@gmail.com>2014-01-02 13:32:55 +0100
commit042b72bc172e7eb4e9ef7668ae28be6e7a3b4036 (patch)
tree7e3d265d3d1fde9f80f3f4623c2f59a5b0521b65 /src
parentMerge branch 'master' into threadsafequeue (diff)
downloadcuberite-042b72bc172e7eb4e9ef7668ae28be6e7a3b4036.tar
cuberite-042b72bc172e7eb4e9ef7668ae28be6e7a3b4036.tar.gz
cuberite-042b72bc172e7eb4e9ef7668ae28be6e7a3b4036.tar.bz2
cuberite-042b72bc172e7eb4e9ef7668ae28be6e7a3b4036.tar.lz
cuberite-042b72bc172e7eb4e9ef7668ae28be6e7a3b4036.tar.xz
cuberite-042b72bc172e7eb4e9ef7668ae28be6e7a3b4036.tar.zst
cuberite-042b72bc172e7eb4e9ef7668ae28be6e7a3b4036.zip
Diffstat (limited to 'src')
-rw-r--r--src/OSSupport/Promise.cpp54
-rw-r--r--src/OSSupport/Promise.h38
-rw-r--r--src/OSSupport/Queue.h24
-rw-r--r--src/World.cpp5
-rw-r--r--src/WorldStorage/WorldStorage.cpp21
-rw-r--r--src/WorldStorage/WorldStorage.h3
6 files changed, 24 insertions, 121 deletions
diff --git a/src/OSSupport/Promise.cpp b/src/OSSupport/Promise.cpp
deleted file mode 100644
index b31869334..000000000
--- a/src/OSSupport/Promise.cpp
+++ /dev/null
@@ -1,54 +0,0 @@
-
-#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
deleted file mode 100644
index 83d04860b..000000000
--- a/src/OSSupport/Promise.h
+++ /dev/null
@@ -1,38 +0,0 @@
-#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 eb323b067..153e201c1 100644
--- a/src/OSSupport/Queue.h
+++ b/src/OSSupport/Queue.h
@@ -3,8 +3,6 @@
#include <list>
-#include "../OSSupport/Promise.h"
-
//this empty struct allows function inlining
template<class T>
struct cQueueFuncs
@@ -52,6 +50,7 @@ public:
if (m_contents.size() == 0) return false;
item = m_contents.front();
m_contents.pop_front();
+ m_evtRemoved.Set();
return true;
}
ItemType DequeueItem()
@@ -62,10 +61,15 @@ public:
cCSUnlock Unlock(m_CS);
m_evtAdded.Wait();
}
- return m_contents.pop_front();
+ ItemType item = m_contents.front();
+ m_contents.pop_front();
+ m_evtRemoved.Set();
+ return item;
}
- cPromise* BlockTillEmpty() {
- return new cEmptyQueuePromise(this);
+ 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()
@@ -87,18 +91,12 @@ public:
{
cCSLock Lock(m_CS);
m_contents.remove(item);
+ m_evtRemoved.Set();
}
private:
ListType m_contents;
cCriticalSection m_CS;
cEvent m_evtAdded;
-
- 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;
- };
+ cEvent m_evtRemoved;
};
diff --git a/src/World.cpp b/src/World.cpp
index cc543d460..39300d419 100644
--- a/src/World.cpp
+++ b/src/World.cpp
@@ -367,10 +367,13 @@ void cWorld::InitializeSpawn(void)
cWorldLoadProgress Progress(this);
// Wait for the loader to finish loading
- m_Storage.WaitForQueuesEmpty();
+ m_Storage.WaitForLoadQueueEmpty();
// Wait for the generator to finish generating
m_Generator.WaitForQueueEmpty();
+
+ // Wait for the loader to finish saving
+ m_Storage.WaitForSaveQueueEmpty();
Progress.Stop();
}
diff --git a/src/WorldStorage/WorldStorage.cpp b/src/WorldStorage/WorldStorage.cpp
index c3bfbd4f6..9ad995c82 100644
--- a/src/WorldStorage/WorldStorage.cpp
+++ b/src/WorldStorage/WorldStorage.cpp
@@ -13,7 +13,6 @@
#include "../Generating/ChunkGenerator.h"
#include "../Entities/Entity.h"
#include "../BlockEntities/BlockEntity.h"
-#include "../OSSupport/Promise.h"
@@ -100,7 +99,7 @@ void cWorldStorage::WaitForFinish(void)
}
// Wait for the saving to finish:
- WaitForQueuesEmpty();
+ WaitForSaveQueueEmpty();
// Wait for the thread to finish:
m_ShouldTerminate = true;
@@ -114,21 +113,15 @@ void cWorldStorage::WaitForFinish(void)
-void cWorldStorage::WaitForQueuesEmpty(void)
+void cWorldStorage::WaitForLoadQueueEmpty(void)
{
-
- cPromise * LoadPromise = m_LoadQueue.BlockTillEmpty();
- cPromise * SavePromise = m_SaveQueue.BlockTillEmpty();
- cPromise * QueuePromise = LoadPromise->WaitFor(SavePromise);
- cPromise * CancelPromise = QueuePromise->CancelOn(m_ShouldTerminate);
- CancelPromise->Wait();
- delete CancelPromise;
- delete QueuePromise;
- delete SavePromise;
- delete LoadPromise;
+ m_LoadQueue.BlockTillEmpty();
}
-
+void cWorldStorage::WaitForSaveQueueEmpty(void)
+{
+ m_SaveQueue.BlockTillEmpty();
+}
diff --git a/src/WorldStorage/WorldStorage.h b/src/WorldStorage/WorldStorage.h
index c3eb96ce8..98eb5fce7 100644
--- a/src/WorldStorage/WorldStorage.h
+++ b/src/WorldStorage/WorldStorage.h
@@ -79,7 +79,8 @@ public:
bool Start(cWorld * a_World, const AString & a_StorageSchemaName); // Hide the cIsThread's Start() method, we need to provide args
void Stop(void); // Hide the cIsThread's Stop() method, we need to signal the event
void WaitForFinish(void);
- void WaitForQueuesEmpty(void);
+ void WaitForLoadQueueEmpty(void);
+ void WaitForSaveQueueEmpty(void);
size_t GetLoadQueueLength(void);
size_t GetSaveQueueLength(void);