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 "CompletionData.h"
|
||||||
#include "Utils.h"
|
#include "Utils.h"
|
||||||
#include "ClangUtils.h"
|
#include "ClangUtils.h"
|
||||||
|
#include "ReleaseGil.h"
|
||||||
|
|
||||||
#include <clang-c/Index.h>
|
#include <clang-c/Index.h>
|
||||||
#include <boost/shared_ptr.hpp>
|
#include <boost/shared_ptr.hpp>
|
||||||
@ -59,6 +60,7 @@ ClangCompleter::~ClangCompleter() {
|
|||||||
|
|
||||||
|
|
||||||
bool ClangCompleter::UpdatingTranslationUnit( const std::string &filename ) {
|
bool ClangCompleter::UpdatingTranslationUnit( const std::string &filename ) {
|
||||||
|
ReleaseGil unlock;
|
||||||
shared_ptr< TranslationUnit > unit = translation_unit_store_.Get( filename );
|
shared_ptr< TranslationUnit > unit = translation_unit_store_.Get( filename );
|
||||||
|
|
||||||
if ( !unit )
|
if ( !unit )
|
||||||
@ -75,6 +77,7 @@ std::vector< Diagnostic > ClangCompleter::UpdateTranslationUnit(
|
|||||||
const std::string &filename,
|
const std::string &filename,
|
||||||
const std::vector< UnsavedFile > &unsaved_files,
|
const std::vector< UnsavedFile > &unsaved_files,
|
||||||
const std::vector< std::string > &flags ) {
|
const std::vector< std::string > &flags ) {
|
||||||
|
ReleaseGil unlock;
|
||||||
bool translation_unit_created;
|
bool translation_unit_created;
|
||||||
shared_ptr< TranslationUnit > unit = translation_unit_store_.GetOrCreate(
|
shared_ptr< TranslationUnit > unit = translation_unit_store_.GetOrCreate(
|
||||||
filename,
|
filename,
|
||||||
@ -111,6 +114,7 @@ ClangCompleter::CandidatesForLocationInFile(
|
|||||||
int column,
|
int column,
|
||||||
const std::vector< UnsavedFile > &unsaved_files,
|
const std::vector< UnsavedFile > &unsaved_files,
|
||||||
const std::vector< std::string > &flags ) {
|
const std::vector< std::string > &flags ) {
|
||||||
|
ReleaseGil unlock;
|
||||||
shared_ptr< TranslationUnit > unit =
|
shared_ptr< TranslationUnit > unit =
|
||||||
translation_unit_store_.GetOrCreate( filename, unsaved_files, flags );
|
translation_unit_store_.GetOrCreate( filename, unsaved_files, flags );
|
||||||
|
|
||||||
@ -129,6 +133,7 @@ Location ClangCompleter::GetDeclarationLocation(
|
|||||||
int column,
|
int column,
|
||||||
const std::vector< UnsavedFile > &unsaved_files,
|
const std::vector< UnsavedFile > &unsaved_files,
|
||||||
const std::vector< std::string > &flags ) {
|
const std::vector< std::string > &flags ) {
|
||||||
|
ReleaseGil unlock;
|
||||||
shared_ptr< TranslationUnit > unit =
|
shared_ptr< TranslationUnit > unit =
|
||||||
translation_unit_store_.GetOrCreate( filename, unsaved_files, flags );
|
translation_unit_store_.GetOrCreate( filename, unsaved_files, flags );
|
||||||
|
|
||||||
@ -146,6 +151,7 @@ Location ClangCompleter::GetDefinitionLocation(
|
|||||||
int column,
|
int column,
|
||||||
const std::vector< UnsavedFile > &unsaved_files,
|
const std::vector< UnsavedFile > &unsaved_files,
|
||||||
const std::vector< std::string > &flags ) {
|
const std::vector< std::string > &flags ) {
|
||||||
|
ReleaseGil unlock;
|
||||||
shared_ptr< TranslationUnit > unit =
|
shared_ptr< TranslationUnit > unit =
|
||||||
translation_unit_store_.GetOrCreate( filename, unsaved_files, flags );
|
translation_unit_store_.GetOrCreate( filename, unsaved_files, flags );
|
||||||
|
|
||||||
@ -158,6 +164,7 @@ Location ClangCompleter::GetDefinitionLocation(
|
|||||||
|
|
||||||
|
|
||||||
void ClangCompleter::DeleteCachesForFile( const std::string &filename ) {
|
void ClangCompleter::DeleteCachesForFile( const std::string &filename ) {
|
||||||
|
ReleaseGil unlock;
|
||||||
translation_unit_store_.Remove( filename );
|
translation_unit_store_.Remove( filename );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -18,6 +18,7 @@
|
|||||||
#include "CompilationDatabase.h"
|
#include "CompilationDatabase.h"
|
||||||
#include "ClangUtils.h"
|
#include "ClangUtils.h"
|
||||||
#include "standard.h"
|
#include "standard.h"
|
||||||
|
#include "ReleaseGil.h"
|
||||||
|
|
||||||
#include <boost/shared_ptr.hpp>
|
#include <boost/shared_ptr.hpp>
|
||||||
#include <boost/make_shared.hpp>
|
#include <boost/make_shared.hpp>
|
||||||
@ -58,6 +59,7 @@ bool CompilationDatabase::DatabaseSuccessfullyLoaded() {
|
|||||||
|
|
||||||
CompilationInfoForFile CompilationDatabase::GetCompilationInfoForFile(
|
CompilationInfoForFile CompilationDatabase::GetCompilationInfoForFile(
|
||||||
const std::string &path_to_file ) {
|
const std::string &path_to_file ) {
|
||||||
|
ReleaseGil unlock;
|
||||||
CompilationInfoForFile info;
|
CompilationInfoForFile info;
|
||||||
|
|
||||||
if ( !is_loaded_ )
|
if ( !is_loaded_ )
|
||||||
|
@ -22,6 +22,7 @@
|
|||||||
#include "IdentifierUtils.h"
|
#include "IdentifierUtils.h"
|
||||||
#include "Result.h"
|
#include "Result.h"
|
||||||
#include "Utils.h"
|
#include "Utils.h"
|
||||||
|
#include "ReleaseGil.h"
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
|
||||||
@ -49,6 +50,7 @@ void IdentifierCompleter::AddIdentifiersToDatabase(
|
|||||||
const std::vector< std::string > &new_candidates,
|
const std::vector< std::string > &new_candidates,
|
||||||
const std::string &filetype,
|
const std::string &filetype,
|
||||||
const std::string &filepath ) {
|
const std::string &filepath ) {
|
||||||
|
ReleaseGil unlock;
|
||||||
identifier_database_.AddIdentifiers( new_candidates,
|
identifier_database_.AddIdentifiers( new_candidates,
|
||||||
filetype,
|
filetype,
|
||||||
filepath );
|
filepath );
|
||||||
@ -57,6 +59,7 @@ void IdentifierCompleter::AddIdentifiersToDatabase(
|
|||||||
|
|
||||||
void IdentifierCompleter::AddIdentifiersToDatabaseFromTagFiles(
|
void IdentifierCompleter::AddIdentifiersToDatabaseFromTagFiles(
|
||||||
const std::vector< std::string > &absolute_paths_to_tag_files ) {
|
const std::vector< std::string > &absolute_paths_to_tag_files ) {
|
||||||
|
ReleaseGil unlock;
|
||||||
foreach( const std::string & path, absolute_paths_to_tag_files ) {
|
foreach( const std::string & path, absolute_paths_to_tag_files ) {
|
||||||
identifier_database_.AddIdentifiers(
|
identifier_database_.AddIdentifiers(
|
||||||
ExtractIdentifiersFromTagsFile( path ) );
|
ExtractIdentifiersFromTagsFile( path ) );
|
||||||
@ -69,6 +72,7 @@ void IdentifierCompleter::AddIdentifiersToDatabaseFromBuffer(
|
|||||||
const std::string &filetype,
|
const std::string &filetype,
|
||||||
const std::string &filepath,
|
const std::string &filepath,
|
||||||
bool collect_from_comments_and_strings ) {
|
bool collect_from_comments_and_strings ) {
|
||||||
|
ReleaseGil unlock;
|
||||||
identifier_database_.ClearCandidatesStoredForFile( filetype, filepath );
|
identifier_database_.ClearCandidatesStoredForFile( filetype, filepath );
|
||||||
|
|
||||||
std::string new_contents =
|
std::string new_contents =
|
||||||
@ -92,6 +96,7 @@ std::vector< std::string > IdentifierCompleter::CandidatesForQuery(
|
|||||||
std::vector< std::string > IdentifierCompleter::CandidatesForQueryAndType(
|
std::vector< std::string > IdentifierCompleter::CandidatesForQueryAndType(
|
||||||
const std::string &query,
|
const std::string &query,
|
||||||
const std::string &filetype ) const {
|
const std::string &filetype ) const {
|
||||||
|
ReleaseGil unlock;
|
||||||
std::vector< Result > results;
|
std::vector< Result > results;
|
||||||
identifier_database_.ResultsForQueryAndType( query, filetype, results );
|
identifier_database_.ResultsForQueryAndType( query, filetype, results );
|
||||||
|
|
||||||
|
@ -20,6 +20,8 @@
|
|||||||
#include "Result.h"
|
#include "Result.h"
|
||||||
#include "Candidate.h"
|
#include "Candidate.h"
|
||||||
#include "CandidateRepository.h"
|
#include "CandidateRepository.h"
|
||||||
|
#include "ReleaseGil.h"
|
||||||
|
|
||||||
#include <boost/algorithm/string.hpp>
|
#include <boost/algorithm/string.hpp>
|
||||||
#include <boost/algorithm/cxx11/any_of.hpp>
|
#include <boost/algorithm/cxx11/any_of.hpp>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
@ -76,15 +78,16 @@ boost::python::list FilterAndSortCandidates(
|
|||||||
return candidates;
|
return candidates;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int num_candidates = len( candidates );
|
||||||
std::vector< const Candidate * > repository_candidates =
|
std::vector< const Candidate * > repository_candidates =
|
||||||
CandidatesFromObjectList( candidates, candidate_property );
|
CandidatesFromObjectList( candidates, candidate_property );
|
||||||
|
|
||||||
|
std::vector< ResultAnd< int > > object_and_results;
|
||||||
|
{
|
||||||
|
ReleaseGil unlock;
|
||||||
Bitset query_bitset = LetterBitsetFromString( query );
|
Bitset query_bitset = LetterBitsetFromString( query );
|
||||||
bool query_has_uppercase_letters = any_of( query, is_upper() );
|
bool query_has_uppercase_letters = any_of( query, is_upper() );
|
||||||
|
|
||||||
int num_candidates = len( candidates );
|
|
||||||
std::vector< ResultAnd< int > > object_and_results;
|
|
||||||
|
|
||||||
for ( int i = 0; i < num_candidates; ++i ) {
|
for ( int i = 0; i < num_candidates; ++i ) {
|
||||||
const Candidate *candidate = repository_candidates[ i ];
|
const Candidate *candidate = repository_candidates[ i ];
|
||||||
|
|
||||||
@ -101,6 +104,7 @@ boost::python::list FilterAndSortCandidates(
|
|||||||
}
|
}
|
||||||
|
|
||||||
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,
|
foreach ( const ResultAnd< int > &object_and_result,
|
||||||
object_and_results ) {
|
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}
|
target_link_libraries( ${PROJECT_NAME}
|
||||||
ycm_core
|
ycm_core
|
||||||
gmock_main )
|
gmock )
|
||||||
|
|
||||||
|
|
||||||
if ( NOT CMAKE_GENERATOR_IS_XCODE )
|
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
|
// We increment this every time when we want to force users to recompile
|
||||||
// ycm_core.
|
// ycm_core.
|
||||||
return 5;
|
return 6;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -54,6 +54,9 @@ BOOST_PYTHON_MODULE(ycm_core)
|
|||||||
using namespace boost::python;
|
using namespace boost::python;
|
||||||
using namespace YouCompleteMe;
|
using namespace YouCompleteMe;
|
||||||
|
|
||||||
|
// Necessary because of usage of the ReleaseGil class
|
||||||
|
PyEval_InitThreads();
|
||||||
|
|
||||||
def( "HasClangSupport", HasClangSupport );
|
def( "HasClangSupport", HasClangSupport );
|
||||||
def( "FilterAndSortCandidates", FilterAndSortCandidates );
|
def( "FilterAndSortCandidates", FilterAndSortCandidates );
|
||||||
def( "YcmCoreVersion", YcmCoreVersion );
|
def( "YcmCoreVersion", YcmCoreVersion );
|
||||||
|
@ -152,7 +152,7 @@ def AdjustCandidateInsertionText( candidates ):
|
|||||||
return new_candidates
|
return new_candidates
|
||||||
|
|
||||||
|
|
||||||
COMPATIBLE_WITH_CORE_VERSION = 5
|
COMPATIBLE_WITH_CORE_VERSION = 6
|
||||||
|
|
||||||
def CompatibleWithYcmCore():
|
def CompatibleWithYcmCore():
|
||||||
try:
|
try:
|
||||||
|
Loading…
x
Reference in New Issue
Block a user