From fcb9b281e061ac9cbb437124a7b980de2613a354 Mon Sep 17 00:00:00 2001 From: "madmaxoft@gmail.com" Date: Tue, 27 Mar 2012 19:23:44 +0000 Subject: Fixed a possible crash in ChunkSender - a client would be reported as removed but still would be in the internal queue. git-svn-id: http://mc-server.googlecode.com/svn/trunk@438 0a769ca7-a7f5-676a-18bf-c427514a06d6 --- source/ChunkSender.cpp | 17 +++++++++++++++-- source/ChunkSender.h | 1 + 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/source/ChunkSender.cpp b/source/ChunkSender.cpp index da134eb8f..517150d1d 100644 --- a/source/ChunkSender.cpp +++ b/source/ChunkSender.cpp @@ -105,6 +105,7 @@ void cChunkSender::RemoveClient(cClientHandle * a_Client) } ++itr; } // for itr - m_SendChunks[] + m_RemoveCount++; } m_evtQueue.Set(); m_evtRemoved.Wait(); // Wait for removal confirmation @@ -121,8 +122,13 @@ void cChunkSender::Execute(void) cCSLock Lock(m_CS); while (m_ChunksReady.empty() && m_SendChunks.empty()) { + int RemoveCount = m_RemoveCount; + m_RemoveCount = 0; cCSUnlock Unlock(Lock); - m_evtRemoved.Set(); // Notify that the removed clients are safe to be deleted + for (int i = 0; i < RemoveCount; i++) + { + m_evtRemoved.Set(); // Notify that the removed clients are safe to be deleted + } m_evtQueue.Wait(); if (m_ShouldTerminate) { @@ -148,7 +154,14 @@ 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 + Lock.Lock(); + int RemoveCount = m_RemoveCount; + m_RemoveCount = 0; + Lock.Unlock(); + for (int i = 0; i < RemoveCount; i++) + { + 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 59fab5b6c..ae9a8b5c5 100644 --- a/source/ChunkSender.h +++ b/source/ChunkSender.h @@ -99,6 +99,7 @@ protected: 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 + int m_RemoveCount; // Number of threads waiting for a client removal (m_evtRemoved needs to be set this many times) // Data about the chunk that is being sent: // NOTE that m_BlockData[] is inherited from the cChunkDataCollector -- cgit v1.2.3