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 -#include "../OSSupport/Promise.h" - //this empty struct allows function inlining template 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);