Serialize clang_createIndex to prevent race condition (concurrent modify/read to FirstTarget defined in lib/Support/TargetRegistry.cpp)

This commit is contained in:
Fangrui Song 2017-12-07 00:23:40 -08:00 committed by Jacob Dufault
parent 702a36d264
commit 77ccee10ce
2 changed files with 10 additions and 13 deletions

View File

@ -1,13 +1,22 @@
#include "clang_index.h" #include "clang_index.h"
#include <mutex>
ClangIndex::ClangIndex() : ClangIndex(1, 0) {} ClangIndex::ClangIndex() : ClangIndex(1, 0) {}
ClangIndex::ClangIndex(int exclude_declarations_from_pch, ClangIndex::ClangIndex(int exclude_declarations_from_pch,
int display_diagnostics) { int display_diagnostics) {
// llvm::InitializeAllTargets (and possibly others) called by clang_createIndex
// transtively modifies/reads lib/Support/TargetRegistry.cpp FirstTarget.
// There will be a race condition if two threads call clang_createIndex
// concurrently.
static std::mutex mutex_;
std::lock_guard<std::mutex> lock(mutex_);
cx_index = cx_index =
clang_createIndex(exclude_declarations_from_pch, display_diagnostics); clang_createIndex(exclude_declarations_from_pch, display_diagnostics);
} }
ClangIndex::~ClangIndex() { ClangIndex::~ClangIndex() {
clang_disposeIndex(cx_index); clang_disposeIndex(cx_index);
} }

View File

@ -14,16 +14,6 @@
namespace { namespace {
// We need to serialize requests to clang_parseTranslationUnit2FullArgv and
// clang_reparseTranslationUnit. See
// https://github.com/jacobdufault/cquery/issues/43#issuecomment-347614504.
//
// NOTE: This is disabled because it effectively serializes indexing, as a huge
// chunk of indexing time is spent inside of these functions.
//
// std::mutex g_parse_translation_unit_mutex;
// std::mutex g_reparse_translation_unit_mutex;
void EmitDiagnostics(std::string path, void EmitDiagnostics(std::string path,
std::vector<const char*> args, std::vector<const char*> args,
CXTranslationUnit tu) { CXTranslationUnit tu) {
@ -95,7 +85,6 @@ std::unique_ptr<ClangTranslationUnit> ClangTranslationUnit::Create(
CXTranslationUnit cx_tu; CXTranslationUnit cx_tu;
CXErrorCode error_code; CXErrorCode error_code;
{ {
// std::lock_guard<std::mutex> lock(g_parse_translation_unit_mutex);
error_code = clang_parseTranslationUnit2FullArgv( error_code = clang_parseTranslationUnit2FullArgv(
index->cx_index, filepath.c_str(), args.data(), (int)args.size(), index->cx_index, filepath.c_str(), args.data(), (int)args.size(),
unsaved_files.data(), (unsigned)unsaved_files.size(), flags, &cx_tu); unsaved_files.data(), (unsigned)unsaved_files.size(), flags, &cx_tu);
@ -134,7 +123,6 @@ std::unique_ptr<ClangTranslationUnit> ClangTranslationUnit::Reparse(
std::vector<CXUnsavedFile>& unsaved) { std::vector<CXUnsavedFile>& unsaved) {
int error_code; int error_code;
{ {
// std::lock_guard<std::mutex> lock(g_reparse_translation_unit_mutex);
error_code = clang_reparseTranslationUnit( error_code = clang_reparseTranslationUnit(
tu->cx_tu, (unsigned)unsaved.size(), unsaved.data(), tu->cx_tu, (unsigned)unsaved.size(), unsaved.data(),
clang_defaultReparseOptions(tu->cx_tu)); clang_defaultReparseOptions(tu->cx_tu));