Cache deletion is now async
This commit is contained in:
parent
1fce7ccec2
commit
4cb9f17c5f
@ -262,13 +262,21 @@ ClangCompleter::CandidatesForQueryAndLocationInFileAsync(
|
||||
}
|
||||
|
||||
|
||||
void ClangCompleter::DeleteCachesForFile( const std::string &filename ) {
|
||||
// If the clang thread is currently parsing the file when the user deletes the
|
||||
// buffer and thus we try to delete the caches, Vim's GUI thread would block
|
||||
// until the clang thread releases the mutex. Move this operation to the clang
|
||||
// thread.
|
||||
void ClangCompleter::DeleteCachesForFileAsync( const std::string &filename ) {
|
||||
file_cache_delete_stack_.Push( filename );
|
||||
}
|
||||
|
||||
|
||||
void ClangCompleter::DeleteCaches() {
|
||||
std::vector< std::string > filenames;
|
||||
if ( !file_cache_delete_stack_.PopAllNoWait( filenames ) )
|
||||
return;
|
||||
|
||||
lock_guard< mutex > lock( filename_to_translation_unit_mutex_ );
|
||||
filename_to_translation_unit_.erase( filename );
|
||||
|
||||
foreach( const std::string &filename, filenames ) {
|
||||
filename_to_translation_unit_.erase( filename );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -466,8 +474,10 @@ void ClangCompleter::ClangThreadMain() {
|
||||
else
|
||||
task->parsing_task_();
|
||||
|
||||
if ( !has_completions_task )
|
||||
if ( !has_completions_task ) {
|
||||
DeleteCaches();
|
||||
continue;
|
||||
}
|
||||
|
||||
unique_future< AsyncCompletions > future =
|
||||
task->completions_task_.get_future();
|
||||
|
@ -19,6 +19,7 @@
|
||||
#define CLANGCOMPLETE_H_WLKDU0ZV
|
||||
|
||||
#include "ConcurrentLatestValue.h"
|
||||
#include "ConcurrentStack.h"
|
||||
#include "Future.h"
|
||||
#include "UnsavedFile.h"
|
||||
#include "Diagnostic.h"
|
||||
@ -93,10 +94,12 @@ public:
|
||||
const std::vector< UnsavedFile > &unsaved_files,
|
||||
const std::vector< std::string > &flags );
|
||||
|
||||
void DeleteCachesForFile( const std::string &filename );
|
||||
void DeleteCachesForFileAsync( const std::string &filename );
|
||||
|
||||
private:
|
||||
|
||||
void DeleteCaches();
|
||||
|
||||
// This is basically a union. Only one of the two tasks is set to something
|
||||
// valid, the other task is invalid. Which one is valid depends on the caller.
|
||||
struct ClangPackagedTask {
|
||||
@ -111,6 +114,8 @@ private:
|
||||
typedef ConcurrentLatestValue <
|
||||
boost::shared_ptr< ClangPackagedTask > > LatestClangTask;
|
||||
|
||||
typedef ConcurrentStack< std::string > FileCacheDeleteStack;
|
||||
|
||||
bool ShouldSkipClangResultCache( const std::string &query,
|
||||
int line,
|
||||
int column );
|
||||
@ -173,6 +178,8 @@ private:
|
||||
|
||||
ClangResultsCache latest_clang_results_;
|
||||
|
||||
FileCacheDeleteStack file_cache_delete_stack_;
|
||||
|
||||
// Unfortunately clang is not thread-safe so we need to be careful when we
|
||||
// access it. Only one thread at a time is allowed to access any single
|
||||
// translation unit. Currently we only use one thread to access clang and that
|
||||
|
@ -37,6 +37,7 @@ public:
|
||||
condition_variable_.notify_one();
|
||||
}
|
||||
|
||||
|
||||
T Pop() {
|
||||
boost::unique_lock< boost::mutex > lock( mutex_ );
|
||||
|
||||
@ -49,6 +50,33 @@ public:
|
||||
return top;
|
||||
}
|
||||
|
||||
|
||||
// Gets all the items from the stack and appends them to the input vector.
|
||||
// Does not wait for the stack to get items; if the stack is empty, returns
|
||||
// false and does not touch the input vector.
|
||||
bool PopAllNoWait( std::vector< T > &items ) {
|
||||
boost::unique_lock< boost::mutex > lock( mutex_ );
|
||||
|
||||
if ( stack_.empty() )
|
||||
return false;
|
||||
|
||||
int num_items = stack_.size();
|
||||
items.reserve( num_items + items.size() );
|
||||
|
||||
for ( int i = 0; i < num_items; ++i ) {
|
||||
items.push_back( stack_.top() );
|
||||
stack_.pop();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool Empty() {
|
||||
boost::unique_lock< boost::mutex > lock( mutex_ );
|
||||
return stack_.empty();
|
||||
}
|
||||
|
||||
private:
|
||||
std::stack< T > stack_;
|
||||
boost::mutex mutex_;
|
||||
|
@ -115,7 +115,8 @@ BOOST_PYTHON_MODULE(ycm_core)
|
||||
class_< ClangCompleter, boost::noncopyable >( "ClangCompleter" )
|
||||
.def( "EnableThreading", &ClangCompleter::EnableThreading )
|
||||
.def( "DiagnosticsForFile", &ClangCompleter::DiagnosticsForFile )
|
||||
.def( "DeleteCachesForFile", &ClangCompleter::DeleteCachesForFile )
|
||||
.def( "DeleteCachesForFileAsync",
|
||||
&ClangCompleter::DeleteCachesForFileAsync )
|
||||
.def( "UpdatingTranslationUnit", &ClangCompleter::UpdatingTranslationUnit )
|
||||
.def( "UpdateTranslationUnitAsync",
|
||||
&ClangCompleter::UpdateTranslationUnitAsync )
|
||||
|
@ -148,7 +148,7 @@ class ClangCompleter( Completer ):
|
||||
|
||||
|
||||
def OnBufferDelete( self, deleted_buffer_file ):
|
||||
self.completer.DeleteCachesForFile( deleted_buffer_file )
|
||||
self.completer.DeleteCachesForFileAsync( deleted_buffer_file )
|
||||
|
||||
|
||||
def DiagnosticsForCurrentFileReady( self ):
|
||||
|
Loading…
x
Reference in New Issue
Block a user