freeze state of WorkingFiles to insulate them from async changes

before shipping unsaved state off to clang
This commit is contained in:
Joel Hock 2018-01-05 23:45:20 -06:00 committed by Jacob Dufault
parent 991b27899f
commit 0c9f572637
3 changed files with 31 additions and 17 deletions

View File

@ -298,7 +298,8 @@ void TryEnsureDocumentParsed(ClangCompleteManager* manager,
args.push_back("-fspell-checking");
}
std::vector<CXUnsavedFile> unsaved = session->working_files->AsUnsavedFiles();
WorkingFilesSnapshot snapshot = session->working_files->AsSnapshot();
std::vector<CXUnsavedFile> unsaved = snapshot.AsUnsavedFiles();
LOG_S(INFO) << "Creating completion session with arguments "
<< StringJoin(args);
@ -388,8 +389,8 @@ void CompletionQueryMain(ClangCompleteManager* completion_manager) {
if (!session->tu)
continue;
std::vector<CXUnsavedFile> unsaved =
completion_manager->working_files_->AsUnsavedFiles();
WorkingFilesSnapshot snapshot = completion_manager->working_files_->AsSnapshot();
std::vector<CXUnsavedFile> unsaved = snapshot.AsUnsavedFiles();
// Emit code completion data.
if (request->position) {

View File

@ -265,14 +265,6 @@ lsPosition WorkingFile::FindStableCompletionSource(
return GetPositionForOffset(buffer_content, offset);
}
CXUnsavedFile WorkingFile::AsUnsavedFile() const {
CXUnsavedFile result;
result.Filename = filename.c_str();
result.Contents = buffer_content.c_str();
result.Length = (unsigned long)buffer_content.size();
return result;
}
WorkingFile* WorkingFiles::GetFileByFilename(const std::string& filename) {
std::lock_guard<std::mutex> lock(files_mutex);
return GetFileByFilenameNoLock(filename);
@ -369,13 +361,27 @@ void WorkingFiles::OnClose(const lsTextDocumentItem& close) {
<< " because it was not open";
}
std::vector<CXUnsavedFile> WorkingFiles::AsUnsavedFiles() {
std::lock_guard<std::mutex> lock(files_mutex);
std::vector<CXUnsavedFile> WorkingFilesSnapshot::AsUnsavedFiles() const {
std::vector<CXUnsavedFile> result;
result.reserve(files.size());
for (auto& file : files) {
CXUnsavedFile unsaved;
unsaved.Filename = file.filename.c_str();
unsaved.Contents = file.content.c_str();
unsaved.Length = (unsigned long)file.content.size();
result.push_back(unsaved);
}
return result;
}
WorkingFilesSnapshot WorkingFiles::AsSnapshot() {
std::lock_guard<std::mutex> lock(files_mutex);
WorkingFilesSnapshot result;
result.files.reserve(files.size());
for (auto& file : files)
result.push_back(file->AsUnsavedFile());
result.files.push_back({file->filename, file->buffer_content});
return result;
}

View File

@ -70,8 +70,15 @@ struct WorkingFile {
lsPosition FindStableCompletionSource(lsPosition position,
bool* is_global_completion,
std::string* existing_completion) const;
};
CXUnsavedFile AsUnsavedFile() const;
struct WorkingFilesSnapshot {
std::vector<CXUnsavedFile> AsUnsavedFiles() const;
struct File {
std::string filename;
std::string content;
};
std::vector<File> files;
};
struct WorkingFiles {
@ -94,7 +101,7 @@ struct WorkingFiles {
void OnChange(const lsTextDocumentDidChangeParams& change);
void OnClose(const lsTextDocumentItem& close);
std::vector<CXUnsavedFile> AsUnsavedFiles();
WorkingFilesSnapshot AsSnapshot();
// Use unique_ptrs so we can handout WorkingFile ptrs and not have them
// invalidated if we resize files.