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 ) {
|
void ClangCompleter::DeleteCachesForFileAsync( const std::string &filename ) {
|
||||||
// If the clang thread is currently parsing the file when the user deletes the
|
file_cache_delete_stack_.Push( filename );
|
||||||
// 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::DeleteCaches() {
|
||||||
|
std::vector< std::string > filenames;
|
||||||
|
if ( !file_cache_delete_stack_.PopAllNoWait( filenames ) )
|
||||||
|
return;
|
||||||
|
|
||||||
lock_guard< mutex > lock( filename_to_translation_unit_mutex_ );
|
lock_guard< mutex > lock( filename_to_translation_unit_mutex_ );
|
||||||
|
|
||||||
|
foreach( const std::string &filename, filenames ) {
|
||||||
filename_to_translation_unit_.erase( filename );
|
filename_to_translation_unit_.erase( filename );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -466,8 +474,10 @@ void ClangCompleter::ClangThreadMain() {
|
|||||||
else
|
else
|
||||||
task->parsing_task_();
|
task->parsing_task_();
|
||||||
|
|
||||||
if ( !has_completions_task )
|
if ( !has_completions_task ) {
|
||||||
|
DeleteCaches();
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
unique_future< AsyncCompletions > future =
|
unique_future< AsyncCompletions > future =
|
||||||
task->completions_task_.get_future();
|
task->completions_task_.get_future();
|
||||||
|
@ -19,6 +19,7 @@
|
|||||||
#define CLANGCOMPLETE_H_WLKDU0ZV
|
#define CLANGCOMPLETE_H_WLKDU0ZV
|
||||||
|
|
||||||
#include "ConcurrentLatestValue.h"
|
#include "ConcurrentLatestValue.h"
|
||||||
|
#include "ConcurrentStack.h"
|
||||||
#include "Future.h"
|
#include "Future.h"
|
||||||
#include "UnsavedFile.h"
|
#include "UnsavedFile.h"
|
||||||
#include "Diagnostic.h"
|
#include "Diagnostic.h"
|
||||||
@ -93,10 +94,12 @@ public:
|
|||||||
const std::vector< UnsavedFile > &unsaved_files,
|
const std::vector< UnsavedFile > &unsaved_files,
|
||||||
const std::vector< std::string > &flags );
|
const std::vector< std::string > &flags );
|
||||||
|
|
||||||
void DeleteCachesForFile( const std::string &filename );
|
void DeleteCachesForFileAsync( const std::string &filename );
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
|
void DeleteCaches();
|
||||||
|
|
||||||
// This is basically a union. Only one of the two tasks is set to something
|
// 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.
|
// valid, the other task is invalid. Which one is valid depends on the caller.
|
||||||
struct ClangPackagedTask {
|
struct ClangPackagedTask {
|
||||||
@ -111,6 +114,8 @@ private:
|
|||||||
typedef ConcurrentLatestValue <
|
typedef ConcurrentLatestValue <
|
||||||
boost::shared_ptr< ClangPackagedTask > > LatestClangTask;
|
boost::shared_ptr< ClangPackagedTask > > LatestClangTask;
|
||||||
|
|
||||||
|
typedef ConcurrentStack< std::string > FileCacheDeleteStack;
|
||||||
|
|
||||||
bool ShouldSkipClangResultCache( const std::string &query,
|
bool ShouldSkipClangResultCache( const std::string &query,
|
||||||
int line,
|
int line,
|
||||||
int column );
|
int column );
|
||||||
@ -173,6 +178,8 @@ private:
|
|||||||
|
|
||||||
ClangResultsCache latest_clang_results_;
|
ClangResultsCache latest_clang_results_;
|
||||||
|
|
||||||
|
FileCacheDeleteStack file_cache_delete_stack_;
|
||||||
|
|
||||||
// Unfortunately clang is not thread-safe so we need to be careful when we
|
// 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
|
// 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
|
// translation unit. Currently we only use one thread to access clang and that
|
||||||
|
@ -37,6 +37,7 @@ public:
|
|||||||
condition_variable_.notify_one();
|
condition_variable_.notify_one();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
T Pop() {
|
T Pop() {
|
||||||
boost::unique_lock< boost::mutex > lock( mutex_ );
|
boost::unique_lock< boost::mutex > lock( mutex_ );
|
||||||
|
|
||||||
@ -49,6 +50,33 @@ public:
|
|||||||
return top;
|
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:
|
private:
|
||||||
std::stack< T > stack_;
|
std::stack< T > stack_;
|
||||||
boost::mutex mutex_;
|
boost::mutex mutex_;
|
||||||
|
@ -115,7 +115,8 @@ BOOST_PYTHON_MODULE(ycm_core)
|
|||||||
class_< ClangCompleter, boost::noncopyable >( "ClangCompleter" )
|
class_< ClangCompleter, boost::noncopyable >( "ClangCompleter" )
|
||||||
.def( "EnableThreading", &ClangCompleter::EnableThreading )
|
.def( "EnableThreading", &ClangCompleter::EnableThreading )
|
||||||
.def( "DiagnosticsForFile", &ClangCompleter::DiagnosticsForFile )
|
.def( "DiagnosticsForFile", &ClangCompleter::DiagnosticsForFile )
|
||||||
.def( "DeleteCachesForFile", &ClangCompleter::DeleteCachesForFile )
|
.def( "DeleteCachesForFileAsync",
|
||||||
|
&ClangCompleter::DeleteCachesForFileAsync )
|
||||||
.def( "UpdatingTranslationUnit", &ClangCompleter::UpdatingTranslationUnit )
|
.def( "UpdatingTranslationUnit", &ClangCompleter::UpdatingTranslationUnit )
|
||||||
.def( "UpdateTranslationUnitAsync",
|
.def( "UpdateTranslationUnitAsync",
|
||||||
&ClangCompleter::UpdateTranslationUnitAsync )
|
&ClangCompleter::UpdateTranslationUnitAsync )
|
||||||
|
@ -148,7 +148,7 @@ class ClangCompleter( Completer ):
|
|||||||
|
|
||||||
|
|
||||||
def OnBufferDelete( self, deleted_buffer_file ):
|
def OnBufferDelete( self, deleted_buffer_file ):
|
||||||
self.completer.DeleteCachesForFile( deleted_buffer_file )
|
self.completer.DeleteCachesForFileAsync( deleted_buffer_file )
|
||||||
|
|
||||||
|
|
||||||
def DiagnosticsForCurrentFileReady( self ):
|
def DiagnosticsForCurrentFileReady( self ):
|
||||||
|
Loading…
x
Reference in New Issue
Block a user