From 4b17105dc45976e399dab68f85b3030fa27f0ae2 Mon Sep 17 00:00:00 2001 From: Rogier Date: Mon, 25 Jul 2016 18:39:29 +0200 Subject: Emergeblocks: Fix occasional crash Modification of the emergeblocks internal state was not protected by a lock, causing a race condition. This can be reproduced by repeatedly running emergeblocks for an already-generated section of the map (with multiple emerge threads). --- src/script/cpp_api/s_env.cpp | 4 +++- src/script/lua_api/l_env.cpp | 4 ++++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/src/script/cpp_api/s_env.cpp b/src/script/cpp_api/s_env.cpp index 82d0d4f0e..913d8539d 100644 --- a/src/script/cpp_api/s_env.cpp +++ b/src/script/cpp_api/s_env.cpp @@ -212,11 +212,13 @@ void ScriptApiEnv::on_emerge_area_completion( { Server *server = getServer(); + // This function should be executed with envlock held. + // The caller (LuaEmergeAreaCallback in src/script/lua_api/l_env.cpp) + // should have obtained the lock. // Note that the order of these locks is important! Envlock must *ALWAYS* // be acquired before attempting to acquire scriptlock, or else ServerThread // will try to acquire scriptlock after it already owns envlock, thus // deadlocking EmergeThread and ServerThread - MutexAutoLock envlock(server->m_env_mutex); SCRIPTAPI_PRECHECKHEADER diff --git a/src/script/lua_api/l_env.cpp b/src/script/lua_api/l_env.cpp index f6ea23e95..68d10308c 100644 --- a/src/script/lua_api/l_env.cpp +++ b/src/script/lua_api/l_env.cpp @@ -137,6 +137,10 @@ void LuaEmergeAreaCallback(v3s16 blockpos, EmergeAction action, void *param) assert(state->script != NULL); assert(state->refcount > 0); + // state must be protected by envlock + Server *server = state->script->getServer(); + MutexAutoLock envlock(server->m_env_mutex); + state->refcount--; state->script->on_emerge_area_completion(blockpos, action, state); -- cgit v1.2.3