Releasing Python's GIL in C++ code where possible
Without this, all requests to the server become effectively serialized.
This commit is contained in:
parent
3ae10395ea
commit
f6432e1498
@ -25,6 +25,7 @@
|
||||
#include "CompletionData.h"
|
||||
#include "Utils.h"
|
||||
#include "ClangUtils.h"
|
||||
#include "ReleaseGil.h"
|
||||
|
||||
#include <clang-c/Index.h>
|
||||
#include <boost/shared_ptr.hpp>
|
||||
@ -59,6 +60,7 @@ ClangCompleter::~ClangCompleter() {
|
||||
|
||||
|
||||
bool ClangCompleter::UpdatingTranslationUnit( const std::string &filename ) {
|
||||
ReleaseGil unlock;
|
||||
shared_ptr< TranslationUnit > unit = translation_unit_store_.Get( filename );
|
||||
|
||||
if ( !unit )
|
||||
@ -75,6 +77,7 @@ std::vector< Diagnostic > ClangCompleter::UpdateTranslationUnit(
|
||||
const std::string &filename,
|
||||
const std::vector< UnsavedFile > &unsaved_files,
|
||||
const std::vector< std::string > &flags ) {
|
||||
ReleaseGil unlock;
|
||||
bool translation_unit_created;
|
||||
shared_ptr< TranslationUnit > unit = translation_unit_store_.GetOrCreate(
|
||||
filename,
|
||||
@ -111,6 +114,7 @@ ClangCompleter::CandidatesForLocationInFile(
|
||||
int column,
|
||||
const std::vector< UnsavedFile > &unsaved_files,
|
||||
const std::vector< std::string > &flags ) {
|
||||
ReleaseGil unlock;
|
||||
shared_ptr< TranslationUnit > unit =
|
||||
translation_unit_store_.GetOrCreate( filename, unsaved_files, flags );
|
||||
|
||||
@ -129,6 +133,7 @@ Location ClangCompleter::GetDeclarationLocation(
|
||||
int column,
|
||||
const std::vector< UnsavedFile > &unsaved_files,
|
||||
const std::vector< std::string > &flags ) {
|
||||
ReleaseGil unlock;
|
||||
shared_ptr< TranslationUnit > unit =
|
||||
translation_unit_store_.GetOrCreate( filename, unsaved_files, flags );
|
||||
|
||||
@ -146,6 +151,7 @@ Location ClangCompleter::GetDefinitionLocation(
|
||||
int column,
|
||||
const std::vector< UnsavedFile > &unsaved_files,
|
||||
const std::vector< std::string > &flags ) {
|
||||
ReleaseGil unlock;
|
||||
shared_ptr< TranslationUnit > unit =
|
||||
translation_unit_store_.GetOrCreate( filename, unsaved_files, flags );
|
||||
|
||||
@ -158,6 +164,7 @@ Location ClangCompleter::GetDefinitionLocation(
|
||||
|
||||
|
||||
void ClangCompleter::DeleteCachesForFile( const std::string &filename ) {
|
||||
ReleaseGil unlock;
|
||||
translation_unit_store_.Remove( filename );
|
||||
}
|
||||
|
||||
|
@ -18,6 +18,7 @@
|
||||
#include "CompilationDatabase.h"
|
||||
#include "ClangUtils.h"
|
||||
#include "standard.h"
|
||||
#include "ReleaseGil.h"
|
||||
|
||||
#include <boost/shared_ptr.hpp>
|
||||
#include <boost/make_shared.hpp>
|
||||
@ -58,6 +59,7 @@ bool CompilationDatabase::DatabaseSuccessfullyLoaded() {
|
||||
|
||||
CompilationInfoForFile CompilationDatabase::GetCompilationInfoForFile(
|
||||
const std::string &path_to_file ) {
|
||||
ReleaseGil unlock;
|
||||
CompilationInfoForFile info;
|
||||
|
||||
if ( !is_loaded_ )
|
||||
|
@ -22,6 +22,7 @@
|
||||
#include "IdentifierUtils.h"
|
||||
#include "Result.h"
|
||||
#include "Utils.h"
|
||||
#include "ReleaseGil.h"
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
@ -49,6 +50,7 @@ void IdentifierCompleter::AddIdentifiersToDatabase(
|
||||
const std::vector< std::string > &new_candidates,
|
||||
const std::string &filetype,
|
||||
const std::string &filepath ) {
|
||||
ReleaseGil unlock;
|
||||
identifier_database_.AddIdentifiers( new_candidates,
|
||||
filetype,
|
||||
filepath );
|
||||
@ -57,6 +59,7 @@ void IdentifierCompleter::AddIdentifiersToDatabase(
|
||||
|
||||
void IdentifierCompleter::AddIdentifiersToDatabaseFromTagFiles(
|
||||
const std::vector< std::string > &absolute_paths_to_tag_files ) {
|
||||
ReleaseGil unlock;
|
||||
foreach( const std::string & path, absolute_paths_to_tag_files ) {
|
||||
identifier_database_.AddIdentifiers(
|
||||
ExtractIdentifiersFromTagsFile( path ) );
|
||||
@ -69,6 +72,7 @@ void IdentifierCompleter::AddIdentifiersToDatabaseFromBuffer(
|
||||
const std::string &filetype,
|
||||
const std::string &filepath,
|
||||
bool collect_from_comments_and_strings ) {
|
||||
ReleaseGil unlock;
|
||||
identifier_database_.ClearCandidatesStoredForFile( filetype, filepath );
|
||||
|
||||
std::string new_contents =
|
||||
@ -92,6 +96,7 @@ std::vector< std::string > IdentifierCompleter::CandidatesForQuery(
|
||||
std::vector< std::string > IdentifierCompleter::CandidatesForQueryAndType(
|
||||
const std::string &query,
|
||||
const std::string &filetype ) const {
|
||||
ReleaseGil unlock;
|
||||
std::vector< Result > results;
|
||||
identifier_database_.ResultsForQueryAndType( query, filetype, results );
|
||||
|
||||
|
@ -20,6 +20,8 @@
|
||||
#include "Result.h"
|
||||
#include "Candidate.h"
|
||||
#include "CandidateRepository.h"
|
||||
#include "ReleaseGil.h"
|
||||
|
||||
#include <boost/algorithm/string.hpp>
|
||||
#include <boost/algorithm/cxx11/any_of.hpp>
|
||||
#include <vector>
|
||||
@ -76,31 +78,33 @@ boost::python::list FilterAndSortCandidates(
|
||||
return candidates;
|
||||
}
|
||||
|
||||
int num_candidates = len( candidates );
|
||||
std::vector< const Candidate * > repository_candidates =
|
||||
CandidatesFromObjectList( candidates, candidate_property );
|
||||
|
||||
Bitset query_bitset = LetterBitsetFromString( query );
|
||||
bool query_has_uppercase_letters = any_of( query, is_upper() );
|
||||
|
||||
int num_candidates = len( candidates );
|
||||
std::vector< ResultAnd< int > > object_and_results;
|
||||
{
|
||||
ReleaseGil unlock;
|
||||
Bitset query_bitset = LetterBitsetFromString( query );
|
||||
bool query_has_uppercase_letters = any_of( query, is_upper() );
|
||||
|
||||
for ( int i = 0; i < num_candidates; ++i ) {
|
||||
const Candidate *candidate = repository_candidates[ i ];
|
||||
for ( int i = 0; i < num_candidates; ++i ) {
|
||||
const Candidate *candidate = repository_candidates[ i ];
|
||||
|
||||
if ( !candidate->MatchesQueryBitset( query_bitset ) )
|
||||
continue;
|
||||
if ( !candidate->MatchesQueryBitset( query_bitset ) )
|
||||
continue;
|
||||
|
||||
Result result = candidate->QueryMatchResult( query,
|
||||
query_has_uppercase_letters );
|
||||
Result result = candidate->QueryMatchResult( query,
|
||||
query_has_uppercase_letters );
|
||||
|
||||
if ( result.IsSubsequence() ) {
|
||||
ResultAnd< int > object_and_result( i, result );
|
||||
object_and_results.push_back( boost::move( object_and_result ) );
|
||||
if ( result.IsSubsequence() ) {
|
||||
ResultAnd< int > object_and_result( i, result );
|
||||
object_and_results.push_back( boost::move( object_and_result ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
std::sort( object_and_results.begin(), object_and_results.end() );
|
||||
std::sort( object_and_results.begin(), object_and_results.end() );
|
||||
}
|
||||
|
||||
foreach ( const ResultAnd< int > &object_and_result,
|
||||
object_and_results ) {
|
||||
|
42
cpp/ycm/ReleaseGil.h
Normal file
42
cpp/ycm/ReleaseGil.h
Normal file
@ -0,0 +1,42 @@
|
||||
// Copyright (C) 2013 Strahinja Val Markovic <val@markovic.io>
|
||||
//
|
||||
// This file is part of YouCompleteMe.
|
||||
//
|
||||
// YouCompleteMe is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// YouCompleteMe is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with YouCompleteMe. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
#ifndef RELEASEGIL_H_RDIEBSQ1
|
||||
#define RELEASEGIL_H_RDIEBSQ1
|
||||
|
||||
#include <boost/python.hpp>
|
||||
|
||||
namespace YouCompleteMe {
|
||||
|
||||
class ReleaseGil {
|
||||
public:
|
||||
ReleaseGil() {
|
||||
thread_state_ = PyEval_SaveThread();
|
||||
}
|
||||
|
||||
~ReleaseGil() {
|
||||
PyEval_RestoreThread( thread_state_ );
|
||||
}
|
||||
|
||||
private:
|
||||
PyThreadState *thread_state_;
|
||||
};
|
||||
|
||||
} // namespace YouCompleteMe
|
||||
|
||||
#endif /* end of include guard: RELEASEGIL_H_RDIEBSQ1 */
|
||||
|
@ -68,7 +68,7 @@ add_executable( ${PROJECT_NAME}
|
||||
|
||||
target_link_libraries( ${PROJECT_NAME}
|
||||
ycm_core
|
||||
gmock_main )
|
||||
gmock )
|
||||
|
||||
|
||||
if ( NOT CMAKE_GENERATOR_IS_XCODE )
|
||||
|
13
cpp/ycm/tests/main.cpp
Normal file
13
cpp/ycm/tests/main.cpp
Normal file
@ -0,0 +1,13 @@
|
||||
#include "gtest/gtest.h"
|
||||
#include "gmock/gmock.h"
|
||||
#include <boost/python.hpp>
|
||||
|
||||
int main( int argc, char **argv ) {
|
||||
Py_Initialize();
|
||||
// Necessary because of usage of the ReleaseGil class
|
||||
PyEval_InitThreads();
|
||||
|
||||
testing::InitGoogleMock(&argc, argv);
|
||||
return RUN_ALL_TESTS();
|
||||
}
|
||||
|
@ -45,7 +45,7 @@ int YcmCoreVersion()
|
||||
{
|
||||
// We increment this every time when we want to force users to recompile
|
||||
// ycm_core.
|
||||
return 5;
|
||||
return 6;
|
||||
}
|
||||
|
||||
|
||||
@ -54,6 +54,9 @@ BOOST_PYTHON_MODULE(ycm_core)
|
||||
using namespace boost::python;
|
||||
using namespace YouCompleteMe;
|
||||
|
||||
// Necessary because of usage of the ReleaseGil class
|
||||
PyEval_InitThreads();
|
||||
|
||||
def( "HasClangSupport", HasClangSupport );
|
||||
def( "FilterAndSortCandidates", FilterAndSortCandidates );
|
||||
def( "YcmCoreVersion", YcmCoreVersion );
|
||||
|
@ -152,7 +152,7 @@ def AdjustCandidateInsertionText( candidates ):
|
||||
return new_candidates
|
||||
|
||||
|
||||
COMPATIBLE_WITH_CORE_VERSION = 5
|
||||
COMPATIBLE_WITH_CORE_VERSION = 6
|
||||
|
||||
def CompatibleWithYcmCore():
|
||||
try:
|
||||
|
Loading…
x
Reference in New Issue
Block a user