summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authormadmaxoft@gmail.com <madmaxoft@gmail.com@0a769ca7-a7f5-676a-18bf-c427514a06d6>2012-03-07 21:06:18 +0100
committermadmaxoft@gmail.com <madmaxoft@gmail.com@0a769ca7-a7f5-676a-18bf-c427514a06d6>2012-03-07 21:06:18 +0100
commit4544d5d3b9fe9c1053f5eaea026b651291712a21 (patch)
tree3854a0eb1e14c0f4b1101985ae0dae12bf914ba2
parentWSSCompact: fixed switched version values (!); removed unused methods (diff)
downloadcuberite-4544d5d3b9fe9c1053f5eaea026b651291712a21.tar
cuberite-4544d5d3b9fe9c1053f5eaea026b651291712a21.tar.gz
cuberite-4544d5d3b9fe9c1053f5eaea026b651291712a21.tar.bz2
cuberite-4544d5d3b9fe9c1053f5eaea026b651291712a21.tar.lz
cuberite-4544d5d3b9fe9c1053f5eaea026b651291712a21.tar.xz
cuberite-4544d5d3b9fe9c1053f5eaea026b651291712a21.tar.zst
cuberite-4544d5d3b9fe9c1053f5eaea026b651291712a21.zip
-rw-r--r--source/ChunkSender.cpp30
-rw-r--r--source/ChunkSender.h13
2 files changed, 27 insertions, 16 deletions
diff --git a/source/ChunkSender.cpp b/source/ChunkSender.cpp
index 3a664962d..f3bc439d1 100644
--- a/source/ChunkSender.cpp
+++ b/source/ChunkSender.cpp
@@ -31,7 +31,7 @@ cChunkSender::cChunkSender(void) :
cChunkSender::~cChunkSender()
{
mShouldTerminate = true;
- m_Event.Set();
+ m_evtQueue.Set();
}
@@ -55,7 +55,7 @@ void cChunkSender::ChunkReady(int a_ChunkX, int a_ChunkY, int a_ChunkZ)
cCSLock Lock(m_CS);
m_ChunksReady.push_back(cChunkCoords(a_ChunkX, a_ChunkY, a_ChunkZ));
}
- m_Event.Set();
+ m_evtQueue.Set();
}
@@ -69,7 +69,7 @@ void cChunkSender::QueueSendChunkTo(int a_ChunkX, int a_ChunkY, int a_ChunkZ, cC
cCSLock Lock(m_CS);
m_SendChunks.push_back(sSendChunk(a_ChunkX, a_ChunkY, a_ChunkZ, a_Client));
}
- m_Event.Set();
+ m_evtQueue.Set();
}
@@ -78,16 +78,20 @@ void cChunkSender::QueueSendChunkTo(int a_ChunkX, int a_ChunkY, int a_ChunkZ, cC
void cChunkSender::RemoveClient(cClientHandle * a_Client)
{
- cCSLock Lock(m_CS);
- for (sSendChunkList::iterator itr = m_SendChunks.begin(); itr != m_SendChunks.end();)
{
- if (itr->m_Client == a_Client)
+ cCSLock Lock(m_CS);
+ for (sSendChunkList::iterator itr = m_SendChunks.begin(); itr != m_SendChunks.end();)
{
- itr = m_SendChunks.erase(itr);
- continue;
- }
- ++itr;
- } // for itr - m_SendChunks[]
+ if (itr->m_Client == a_Client)
+ {
+ itr = m_SendChunks.erase(itr);
+ continue;
+ }
+ ++itr;
+ } // for itr - m_SendChunks[]
+ }
+ m_evtQueue.Set();
+ m_evtRemoved.Wait(); // Wait for removal confirmation
}
@@ -102,7 +106,8 @@ void cChunkSender::Execute(void)
while (m_ChunksReady.empty() && m_SendChunks.empty())
{
cCSUnlock Unlock(Lock);
- m_Event.Wait();
+ m_evtRemoved.Set(); // Notify that the removed clients are safe to be deleted
+ m_evtQueue.Wait();
if (mShouldTerminate)
{
return;
@@ -127,6 +132,7 @@ void cChunkSender::Execute(void)
SendChunk(Chunk.m_ChunkX, Chunk.m_ChunkY, Chunk.m_ChunkZ, Chunk.m_Client);
}
+ m_evtRemoved.Set(); // Notify that the removed clients are safe to be deleted
} // while (!mShouldTerminate)
}
diff --git a/source/ChunkSender.h b/source/ChunkSender.h
index d0e50f341..b2ada5a09 100644
--- a/source/ChunkSender.h
+++ b/source/ChunkSender.h
@@ -15,6 +15,10 @@ Chunk data is queried using the cChunkDataCallback interface.
It is cached inside the ChunkSender object during the query and then processed after the query ends.
Note that the data needs to be compressed only *after* the query finishes,
because the query callbacks run with ChunkMap's CS locked.
+
+A client may remove itself from all direct requests(QueueSendChunkTo()) by calling RemoveClient();
+this ensures that the client's Send() won't be called anymore by ChunkSender.
+Note that it may be called by world's BroadcastToChunk() if the client is still in the chunk.
*/
@@ -78,10 +82,11 @@ protected:
cWorld * m_World;
- cCriticalSection m_CS;
- cChunkCoordsList m_ChunksReady;
- sSendChunkList m_SendChunks;
- cEvent m_Event; // Set when anything is added to m_ChunksReady
+ cCriticalSection m_CS;
+ cChunkCoordsList m_ChunksReady;
+ sSendChunkList m_SendChunks;
+ cEvent m_evtQueue; // Set when anything is added to m_ChunksReady
+ cEvent m_evtRemoved; // Set when removed clients are safe to be deleted
// Data about the chunk that is being sent:
char m_BlockData[cChunk::c_BlockDataSize];