1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64
|
From 824caddcfdd5f4c7740e77ae7e5b5c46b2b1b47f Mon Sep 17 00:00:00 2001
From: David White <davewx7@gmail.com>
Date: Fri, 9 Nov 2012 19:41:34 -0800
Subject: fixed multi-threaded crash in editor tile rendering logic that could
cause intermittent crashes when drawing tiles
diff --git a/src/level.cpp b/src/level.cpp
index 1f96f9dfa..a8ddf87d5 100644
--- a/src/level.cpp
+++ b/src/level.cpp
@@ -837,12 +837,19 @@ void level::start_rebuild_tiles_in_background(const std::vector<int>& layers)
info.rebuild_tile_layers_worker_buffer = info.rebuild_tile_layers_buffer;
info.rebuild_tile_layers_buffer.clear();
+ std::map<int, tile_map> worker_tile_maps = tile_maps_;
+ for(std::map<int, tile_map>::iterator i = worker_tile_maps.begin();
+ i != worker_tile_maps.end(); ++i) {
+ //make the tile maps safe to go into a worker thread.
+ i->second.prepare_for_copy_to_worker_thread();
+ }
+
static threading::mutex* sync = new threading::mutex;
#if defined(__ANDROID__) && SDL_VERSION_ATLEAST(1, 3, 0)
- info.rebuild_tile_thread = new threading::thread("rebuild_tiles", boost::bind(build_tiles_thread_function, &info, tile_maps_, *sync));
+ info.rebuild_tile_thread = new threading::thread("rebuild_tiles", boost::bind(build_tiles_thread_function, &info, worker_tile_maps, *sync));
#else
- info.rebuild_tile_thread = new threading::thread(boost::bind(build_tiles_thread_function, &info, tile_maps_, *sync));
+ info.rebuild_tile_thread = new threading::thread(boost::bind(build_tiles_thread_function, &info, worker_tile_maps, *sync));
#endif
}
diff --git a/src/tile_map.cpp b/src/tile_map.cpp
index e71a0373b..83525b4c0 100644
--- a/src/tile_map.cpp
+++ b/src/tile_map.cpp
@@ -694,6 +694,11 @@ void tile_map::flip_variation(int x, int y, int delta)
}
}
+void tile_map::prepare_for_copy_to_worker_thread()
+{
+ node_ = variant();
+}
+
namespace {
//This function is a random hash. It takes an (x,y) position as well as a
diff --git a/src/tile_map.hpp b/src/tile_map.hpp
index e5245f770..d84862414 100644
--- a/src/tile_map.hpp
+++ b/src/tile_map.hpp
@@ -45,6 +45,10 @@ public:
int get_variations(int x, int y) const;
void flip_variation(int x, int y, int delta=0);
+ //variants are not thread-safe, so this function clears out variant
+ //info to prepare the tile map to be placed into a worker thread.
+ void prepare_for_copy_to_worker_thread();
+
#ifndef NO_EDITOR
//Functions for rebuilding all live tile maps when there is a change
//to tile map data. prepare_rebuild_all() should be called before
|