fix a race in type registration
Summary:
Here's what's happening:
C++ only guarantees that static initialization is thread safe there: https://fburl.com/40wdmf1q
So TypeNameRegisterer<bool> can not be called concurrently with TypeNameRegisterer<bool> from another invocation
But there's no guarantees about different template specializations as
they declare separate variables. Thus TypeNameRegisterer<int> might
race with TypeNameRegisterer<bool>. And TypeNameRegisterer accesses
the global variable here: https://fburl.com/gv2mhi08
Thanks dzhulgakov for the investigation!
Reviewed By: Yangqing
Differential Revision: D5882913
fbshipit-source-id: 4db1080b11e6351ce8136373e2dfc52980642fbb
diff --git a/caffe2/core/typeid.cc b/caffe2/core/typeid.cc
index bc29f3f..896fd63 100644
--- a/caffe2/core/typeid.cc
+++ b/caffe2/core/typeid.cc
@@ -16,6 +16,11 @@
return g_registered_type_names;
}
+std::mutex& gCaffe2TypeRegistrationMutex() {
+ static std::mutex g_caffe2_type_registration_mutex;
+ return g_caffe2_type_registration_mutex;
+}
+
#if defined(_MSC_VER)
// Windows does not have cxxabi.h, so we will simply return the original.
string Demangle(const char* name) {
diff --git a/caffe2/core/typeid.h b/caffe2/core/typeid.h
index 1cede63..ee68dd1 100644
--- a/caffe2/core/typeid.h
+++ b/caffe2/core/typeid.h
@@ -3,9 +3,9 @@
#include <cassert>
#include <cstdlib>
-
#include <iostream>
#include <map>
+#include <mutex>
#include <type_traits>
#ifdef __GXX_RTTI
#include <set>
@@ -31,9 +31,12 @@
// type before its what() content.
string GetExceptionString(const std::exception& e);
+std::mutex& gCaffe2TypeRegistrationMutex();
+
template <typename T>
struct TypeNameRegisterer {
explicit TypeNameRegisterer(CaffeTypeId id) {
+ std::lock_guard<std::mutex> guard(gCaffe2TypeRegistrationMutex());
#ifdef __GXX_RTTI
string name = Demangle(typeid(T).name());
gTypeNames()[id] = name;