Merge "libbacktraceoffline: make it thread-safe." am: a3e4977325 am: 47ac9e420f am: b850b9d589
am: e769f0b564
Change-Id: I6ebfa49bd5ff944a229ddaa8b81919c446c27078
diff --git a/libbacktrace/BacktraceOffline.cpp b/libbacktrace/BacktraceOffline.cpp
index 53ea796..0a2f5a3 100644
--- a/libbacktrace/BacktraceOffline.cpp
+++ b/libbacktrace/BacktraceOffline.cpp
@@ -31,6 +31,7 @@
#include <unistd.h>
#include <memory>
+#include <mutex>
#include <string>
#include <vector>
@@ -91,9 +92,6 @@
has_debug_frame(false), has_gnu_debugdata(false) { }
};
-static std::unordered_map<std::string, std::unique_ptr<DebugFrameInfo>>& g_debug_frames =
- *new std::unordered_map<std::string, std::unique_ptr<DebugFrameInfo>>;
-
void Space::Clear() {
start = 0;
end = 0;
@@ -557,18 +555,31 @@
return "";
}
+static std::mutex g_lock;
+static std::unordered_map<std::string, std::unique_ptr<DebugFrameInfo>>* g_debug_frames = nullptr;
+
static DebugFrameInfo* ReadDebugFrameFromFile(const std::string& filename);
DebugFrameInfo* BacktraceOffline::GetDebugFrameInFile(const std::string& filename) {
if (cache_file_) {
- auto it = g_debug_frames.find(filename);
- if (it != g_debug_frames.end()) {
- return it->second.get();
+ std::lock_guard<std::mutex> lock(g_lock);
+ if (g_debug_frames != nullptr) {
+ auto it = g_debug_frames->find(filename);
+ if (it != g_debug_frames->end()) {
+ return it->second.get();
+ }
}
}
DebugFrameInfo* debug_frame = ReadDebugFrameFromFile(filename);
if (cache_file_) {
- g_debug_frames.emplace(filename, std::unique_ptr<DebugFrameInfo>(debug_frame));
+ std::lock_guard<std::mutex> lock(g_lock);
+ if (g_debug_frames == nullptr) {
+ g_debug_frames = new std::unordered_map<std::string, std::unique_ptr<DebugFrameInfo>>;
+ }
+ auto pair = g_debug_frames->emplace(filename, std::unique_ptr<DebugFrameInfo>(debug_frame));
+ if (!pair.second) {
+ debug_frame = pair.first->second.get();
+ }
}
return debug_frame;
}