From 499745c1c7a865941b3c102532777c19dfb92ca4 Mon Sep 17 00:00:00 2001 From: "madmaxoft@gmail.com" Date: Sat, 18 Feb 2012 17:53:22 +0000 Subject: Thread-safe chunk generation, storage and generator are queried for progress while initializing server Note that this commit breaks foliage generation - there are no trees in the chunks generated! git-svn-id: http://mc-server.googlecode.com/svn/trunk@292 0a769ca7-a7f5-676a-18bf-c427514a06d6 --- source/WorldStorage.cpp | 52 ++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 45 insertions(+), 7 deletions(-) (limited to 'source/WorldStorage.cpp') diff --git a/source/WorldStorage.cpp b/source/WorldStorage.cpp index f6be97753..bc830c272 100644 --- a/source/WorldStorage.cpp +++ b/source/WorldStorage.cpp @@ -147,13 +147,14 @@ void cWorldStorage::WaitForFinish(void) { // Cancel all loading requests: - cCSLock Lock(m_CSLoadQueue); + cCSLock Lock(m_CSQueues); m_LoadQueue.clear(); } // Wait for the thread to finish: mShouldTerminate = true; m_Event.Set(); + m_evtRemoved.Set(); // Wake up anybody waiting in the WaitForQueuesEmpty() method super::Wait(); } @@ -161,10 +162,44 @@ void cWorldStorage::WaitForFinish(void) +void cWorldStorage::WaitForQueuesEmpty(void) +{ + cCSLock Lock(m_CSQueues); + while (!mShouldTerminate && (!m_LoadQueue.empty() || !m_SaveQueue.empty())) + { + cCSUnlock Unlock(Lock); + m_evtRemoved.Wait(); + } +} + + + + + +int cWorldStorage::GetLoadQueueLength(void) +{ + cCSLock Lock(m_CSQueues); + return (int)m_LoadQueue.size(); +} + + + + + +int cWorldStorage::GetSaveQueueLength(void) +{ + cCSLock Lock(m_CSQueues); + return (int)m_SaveQueue.size(); +} + + + + + void cWorldStorage::QueueLoadChunk(int a_ChunkX, int a_ChunkY, int a_ChunkZ) { // Queues the chunk for loading; if not loaded, the chunk will be generated - cCSLock Lock(m_CSLoadQueue); + cCSLock Lock(m_CSQueues); m_LoadQueue.remove (cChunkCoords(a_ChunkX, a_ChunkY, a_ChunkZ)); // Don't add twice m_LoadQueue.push_back(cChunkCoords(a_ChunkX, a_ChunkY, a_ChunkZ)); m_Event.Set(); @@ -176,7 +211,7 @@ void cWorldStorage::QueueLoadChunk(int a_ChunkX, int a_ChunkY, int a_ChunkZ) void cWorldStorage::QueueSaveChunk(int a_ChunkX, int a_ChunkY, int a_ChunkZ) { - cCSLock Lock(m_CSSaveQueue); + cCSLock Lock(m_CSQueues); m_SaveQueue.remove (cChunkCoords(a_ChunkX, a_ChunkY, a_ChunkZ)); // Don't add twice m_SaveQueue.push_back(cChunkCoords(a_ChunkX, a_ChunkY, a_ChunkZ)); m_Event.Set(); @@ -188,8 +223,9 @@ void cWorldStorage::QueueSaveChunk(int a_ChunkX, int a_ChunkY, int a_ChunkZ) void cWorldStorage::UnqueueLoad(const cChunkCoords & a_Chunk) { - cCSLock Lock(m_CSLoadQueue); + cCSLock Lock(m_CSQueues); m_LoadQueue.remove(a_Chunk); + m_evtRemoved.Set(); } @@ -198,8 +234,9 @@ void cWorldStorage::UnqueueLoad(const cChunkCoords & a_Chunk) void cWorldStorage::UnqueueSave(const cChunkCoords & a_Chunk) { - cCSLock Lock(m_CSSaveQueue); + cCSLock Lock(m_CSQueues); m_SaveQueue.remove(a_Chunk); + m_evtRemoved.Set(); } @@ -258,6 +295,7 @@ void cWorldStorage::Execute(void) HasMore = LoadOneChunk(); HasMore = HasMore | SaveOneChunk(); + m_evtRemoved.Set(); } while (HasMore); } } @@ -272,7 +310,7 @@ bool cWorldStorage::LoadOneChunk(void) bool HasMore; bool ShouldLoad = false; { - cCSLock Lock(m_CSLoadQueue); + cCSLock Lock(m_CSQueues); if (m_LoadQueue.size() > 0) { ToLoad = m_LoadQueue.front(); @@ -299,7 +337,7 @@ bool cWorldStorage::SaveOneChunk(void) bool HasMore; bool ShouldSave = false; { - cCSLock Lock(m_CSSaveQueue); + cCSLock Lock(m_CSQueues); if (m_SaveQueue.size() > 0) { Save = m_SaveQueue.front(); -- cgit v1.2.3