]> git.lizzy.rs Git - minetest.git/commitdiff
Emergeblocks: Fix occasional crash
authorRogier <rogier777@gmail.com>
Mon, 25 Jul 2016 16:39:29 +0000 (18:39 +0200)
committerparamat <mat.gregory@virginmedia.com>
Sun, 16 Oct 2016 00:13:16 +0000 (01:13 +0100)
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
src/script/lua_api/l_env.cpp

index 82d0d4f0e2062e69ec99c79fe3321357cece117d..913d8539d30f2cfd4008dc53b44dbbeecefc8ef7 100644 (file)
@@ -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
 
index f6ea23e95826857012b88f971f89a37576de0023..68d10308c9ba14f132b0a6a87b29e82317cd9eba 100644 (file)
@@ -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);