From e34f097543c7a2b733a6d6a8b55a26a6777b5e83 Mon Sep 17 00:00:00 2001 From: "madmaxoft@gmail.com" Date: Sun, 11 Nov 2012 14:00:58 +0000 Subject: Hopefully a fix for crash when chunks are added to a client being destroyed. git-svn-id: http://mc-server.googlecode.com/svn/trunk@1032 0a769ca7-a7f5-676a-18bf-c427514a06d6 --- source/ClientHandle.cpp | 25 +++++++++++++++++++++---- 1 file changed, 21 insertions(+), 4 deletions(-) (limited to 'source/ClientHandle.cpp') diff --git a/source/ClientHandle.cpp b/source/ClientHandle.cpp index 24654d303..fd7ad917e 100644 --- a/source/ClientHandle.cpp +++ b/source/ClientHandle.cpp @@ -78,7 +78,6 @@ cClientHandle::cClientHandle(const cSocket * a_Socket, int a_ViewDistance) : m_ViewDistance(a_ViewDistance) , m_IPString(a_Socket->GetIPString()) , m_OutgoingData(64 KiB) - , m_bDestroyed(false) , m_Player(NULL) , m_bKicking(false) , m_TimeSinceLastPacket(0) @@ -109,6 +108,8 @@ cClientHandle::cClientHandle(const cSocket * a_Socket, int a_ViewDistance) cClientHandle::~cClientHandle() { + ASSERT(m_State == csDestroyed); // Has Destroy() been called? + LOGD("Deleting client \"%s\" at %p", GetUsername().c_str(), this); // Remove from cSocketThreads, we're not to be called anymore: @@ -178,13 +179,13 @@ void cClientHandle::Destroy() // otherwise the destructor may be called within another thread before the client is removed from chunks // http://forum.mc-server.org/showthread.php?tid=366 + m_State = csDestroying; if ((m_Player != NULL) && (m_Player->GetWorld() != NULL)) { RemoveFromAllChunks(); m_Player->GetWorld()->RemoveClientFromChunkSender(this); } - - m_bDestroyed = true; + m_State = csDestroyed; } @@ -268,7 +269,7 @@ void cClientHandle::Authenticate(void) void cClientHandle::StreamChunks(void) { - if (m_State < csAuthenticating) + if ((m_State < csAuthenticating) || (m_State >= csDestroying)) { return; } @@ -367,6 +368,12 @@ void cClientHandle::StreamChunks(void) void cClientHandle::StreamChunk(int a_ChunkX, int a_ChunkY, int a_ChunkZ) { + if (m_State >= csDestroying) + { + // Don't stream chunks to clients that are being destroyed + return; + } + cWorld * World = m_Player->GetWorld(); ASSERT(World != NULL); @@ -1644,6 +1651,11 @@ void cClientHandle::SetViewDistance(int a_ViewDistance) bool cClientHandle::WantsSendChunk(int a_ChunkX, int a_ChunkY, int a_ChunkZ) { + if (m_State >= csDestroying) + { + return false; + } + cCSLock Lock(m_CSChunkLists); return (std::find(m_ChunksToSend.begin(), m_ChunksToSend.end(), cChunkCoords(a_ChunkX, a_ChunkY, a_ChunkZ)) != m_ChunksToSend.end()); } @@ -1654,6 +1666,11 @@ bool cClientHandle::WantsSendChunk(int a_ChunkX, int a_ChunkY, int a_ChunkZ) void cClientHandle::AddWantedChunk(int a_ChunkX, int a_ChunkZ) { + if (m_State >= csDestroying) + { + return; + } + LOGD("Adding chunk [%d, %d] to wanted chunks for client %p", a_ChunkX, a_ChunkZ, this); cCSLock Lock(m_CSChunkLists); if (std::find(m_ChunksToSend.begin(), m_ChunksToSend.end(), cChunkCoords(a_ChunkX, ZERO_CHUNK_Y, a_ChunkZ)) == m_ChunksToSend.end()) -- cgit v1.2.3