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

View File

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

View File

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