Skip to content

Commit

Permalink
Emergeblocks: Fix occasional crash
Browse files Browse the repository at this point in the history
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).
  • Loading branch information
Rogier-5 authored and paramat committed Oct 16, 2016
1 parent adad6e0 commit 4b17105
Show file tree
Hide file tree
Showing 2 changed files with 7 additions and 1 deletion.
4 changes: 3 additions & 1 deletion src/script/cpp_api/s_env.cpp
Expand Up @@ -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

Expand Down
4 changes: 4 additions & 0 deletions src/script/lua_api/l_env.cpp
Expand Up @@ -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);
Expand Down

0 comments on commit 4b17105

Please sign in to comment.