diff --git a/src/libs/sqlite/sqlitedatabase.cpp b/src/libs/sqlite/sqlitedatabase.cpp index aff2ca7069d..6fb57911396 100644 --- a/src/libs/sqlite/sqlitedatabase.cpp +++ b/src/libs/sqlite/sqlitedatabase.cpp @@ -28,6 +28,10 @@ #include "sqlitetable.h" #include "sqlitetransaction.h" +#include + +using namespace std::chrono_literals; + namespace Sqlite { Database::Database() @@ -36,7 +40,15 @@ Database::Database() } Database::Database(Utils::PathString &&databaseFilePath, JournalMode journalMode) - : m_databaseBackend(*this) + : Database(std::move(databaseFilePath), 0ms, journalMode) +{ +} + +Database::Database(Utils::PathString &&databaseFilePath, + std::chrono::milliseconds busyTimeout, + JournalMode journalMode) + : m_databaseBackend(*this), + m_busyTimeout(busyTimeout) { setJournalMode(journalMode); open(std::move(databaseFilePath)); @@ -46,6 +58,7 @@ void Database::open() { m_databaseBackend.open(m_databaseFilePath, m_openMode); m_databaseBackend.setJournalMode(m_journalMode); + m_databaseBackend.setBusyTimeout(m_busyTimeout); initializeTables(); m_isOpen = true; } @@ -129,6 +142,4 @@ DatabaseBackend &Database::backend() return m_databaseBackend; } - - } // namespace Sqlite diff --git a/src/libs/sqlite/sqlitedatabase.h b/src/libs/sqlite/sqlitedatabase.h index a5d43661a9a..83c11860ca6 100644 --- a/src/libs/sqlite/sqlitedatabase.h +++ b/src/libs/sqlite/sqlitedatabase.h @@ -32,6 +32,7 @@ #include +#include #include #include @@ -52,7 +53,11 @@ public: using WriteStatement = Sqlite::WriteStatement; Database(); - Database(Utils::PathString &&databaseFilePath, JournalMode journalMode=JournalMode::Wal); + Database(Utils::PathString &&databaseFilePath, + JournalMode journalMode=JournalMode::Wal); + Database(Utils::PathString &&databaseFilePath, + std::chrono::milliseconds busyTimeout = {}, + JournalMode journalMode=JournalMode::Wal); Database(const Database &) = delete; Database &operator=(const Database &) = delete; @@ -138,6 +143,7 @@ private: DatabaseBackend m_databaseBackend; std::vector m_sqliteTables; std::mutex m_databaseMutex; + std::chrono::milliseconds m_busyTimeout; JournalMode m_journalMode = JournalMode::Wal; OpenMode m_openMode = OpenMode::ReadWrite; bool m_isOpen = false; diff --git a/src/libs/sqlite/sqlitedatabasebackend.cpp b/src/libs/sqlite/sqlitedatabasebackend.cpp index d62e2b2897a..01d6517aa93 100644 --- a/src/libs/sqlite/sqlitedatabasebackend.cpp +++ b/src/libs/sqlite/sqlitedatabasebackend.cpp @@ -105,7 +105,6 @@ void DatabaseBackend::open(Utils::SmallStringView databaseFilePath, OpenMode mod checkDatabaseCouldBeOpened(resultCode); - registerBusyHandler(); registerRankingFunction(); cacheTextEncoding(); } @@ -212,7 +211,9 @@ void DatabaseBackend::closeWithoutException() void DatabaseBackend::registerBusyHandler() { - sqlite3_busy_handler(sqliteDatabaseHandle(), &busyHandlerCallback, nullptr); + int resultCode = sqlite3_busy_handler(sqliteDatabaseHandle(), &busyHandlerCallback, nullptr); + + checkIfBusyTimeoutWasSet(resultCode); } void DatabaseBackend::registerRankingFunction() @@ -326,6 +327,12 @@ void DatabaseBackend::checkIfLogCouldBeCheckpointed(int resultCode) throwException("SqliteDatabaseBackend::checkpointFullWalLog: WAL log could not be checkpointed!"); } +void DatabaseBackend::checkIfBusyTimeoutWasSet(int resultCode) +{ + if (resultCode != SQLITE_OK) + throwException("SqliteDatabaseBackend::setBusyTimeout: Busy timeout cannot be set!"); +} + namespace { template int indexOfPragma(Utils::SmallStringView pragma, const Utils::SmallStringView (&pragmas)[Size]) @@ -395,6 +402,11 @@ int DatabaseBackend::openMode(OpenMode mode) return sqliteMode; } +void DatabaseBackend::setBusyTimeout(std::chrono::milliseconds timeout) +{ + sqlite3_busy_timeout(m_databaseHandle, int(timeout.count())); +} + void DatabaseBackend::throwExceptionStatic(const char *whatHasHappens) { throw Exception(whatHasHappens); diff --git a/src/libs/sqlite/sqlitedatabasebackend.h b/src/libs/sqlite/sqlitedatabasebackend.h index 50a766fd701..db01a707796 100644 --- a/src/libs/sqlite/sqlitedatabasebackend.h +++ b/src/libs/sqlite/sqlitedatabasebackend.h @@ -29,6 +29,8 @@ #include +#include + struct sqlite3; namespace Sqlite { @@ -81,6 +83,8 @@ public: static int openMode(OpenMode); + void setBusyTimeout(std::chrono::milliseconds timeout); + protected: bool databaseIsOpen() const; @@ -105,6 +109,7 @@ protected: void checkInitializeSqliteLibraryWasSuccesful(int resultCode); void checkShutdownSqliteLibraryWasSuccesful(int resultCode); void checkIfLogCouldBeCheckpointed(int resultCode); + void checkIfBusyTimeoutWasSet(int resultCode); static Utils::SmallStringView journalModeToPragma(JournalMode journalMode); static JournalMode pragmaToJournalMode(Utils::SmallStringView pragma); diff --git a/src/plugins/clangpchmanager/clangpchmanagerplugin.cpp b/src/plugins/clangpchmanager/clangpchmanagerplugin.cpp index 00d7097ca4d..5817db90344 100644 --- a/src/plugins/clangpchmanager/clangpchmanagerplugin.cpp +++ b/src/plugins/clangpchmanager/clangpchmanagerplugin.cpp @@ -39,6 +39,10 @@ #include +#include + +using namespace std::chrono_literals; + namespace ClangPchManager { namespace { @@ -55,7 +59,7 @@ QString backendProcessPath() class ClangPchManagerPluginData { public: - Sqlite::Database database{Utils::PathString{Core::ICore::userResourcePath() + "/symbol-experimental-v1.db"}}; + Sqlite::Database database{Utils::PathString{Core::ICore::userResourcePath() + "/symbol-experimental-v1.db"}, 1000ms}; ClangBackEnd::RefactoringDatabaseInitializer databaseInitializer{database}; ClangBackEnd::FilePathCaching filePathCache{database}; PrecompiledHeaderStorage<> preCompiledHeaderStorage{database}; diff --git a/src/plugins/clangrefactoring/clangrefactoringplugin.cpp b/src/plugins/clangrefactoring/clangrefactoringplugin.cpp index 7205b287e47..afbc2f1a9cc 100644 --- a/src/plugins/clangrefactoring/clangrefactoringplugin.cpp +++ b/src/plugins/clangrefactoring/clangrefactoringplugin.cpp @@ -52,6 +52,10 @@ #include #include +#include + +using namespace std::chrono_literals; + namespace ClangRefactoring { namespace { @@ -74,7 +78,7 @@ public: using QuerySqliteReadStatementFactory = QuerySqliteStatementFactory; - Sqlite::Database database{Utils::PathString{Core::ICore::userResourcePath() + "/symbol-experimental-v1.db"}}; + Sqlite::Database database{Utils::PathString{Core::ICore::userResourcePath() + "/symbol-experimental-v1.db"}, 1000ms}; ClangBackEnd::RefactoringDatabaseInitializer databaseInitializer{database}; ClangBackEnd::FilePathCaching filePathCache{database}; RefactoringClient refactoringClient; diff --git a/src/tools/clangpchmanagerbackend/clangpchmanagerbackendmain.cpp b/src/tools/clangpchmanagerbackend/clangpchmanagerbackendmain.cpp index b00ecd6454c..6289e95a176 100644 --- a/src/tools/clangpchmanagerbackend/clangpchmanagerbackendmain.cpp +++ b/src/tools/clangpchmanagerbackend/clangpchmanagerbackendmain.cpp @@ -43,8 +43,11 @@ #include #include +#include #include +using namespace std::chrono_literals; + using ClangBackEnd::ClangPathWatcher; using ClangBackEnd::ConnectionServer; using ClangBackEnd::PchCreator; @@ -109,7 +112,7 @@ int main(int argc, char *argv[]) const QString connectionName = arguments[0]; const QString databasePath = arguments[1]; - Sqlite::Database database{Utils::PathString{databasePath}}; + Sqlite::Database database{Utils::PathString{databasePath}, 1000ms}; ClangBackEnd::RefactoringDatabaseInitializer databaseInitializer{database}; ClangBackEnd::FilePathCaching filePathCache{database}; ClangPathWatcher includeWatcher(filePathCache); diff --git a/src/tools/clangrefactoringbackend/clangrefactoringbackendmain.cpp b/src/tools/clangrefactoringbackend/clangrefactoringbackendmain.cpp index 8c7ee2823f3..f2caace9051 100644 --- a/src/tools/clangrefactoringbackend/clangrefactoringbackendmain.cpp +++ b/src/tools/clangrefactoringbackend/clangrefactoringbackendmain.cpp @@ -35,6 +35,10 @@ #include #include +#include + +using namespace std::chrono_literals; + using ClangBackEnd::FilePathCaching; using ClangBackEnd::RefactoringClientProxy; using ClangBackEnd::RefactoringServer; @@ -74,7 +78,7 @@ int main(int argc, char *argv[]) const QString connectionName = arguments[0]; const QString databasePath = arguments[1]; - Sqlite::Database database{Utils::PathString{databasePath}}; + Sqlite::Database database{Utils::PathString{databasePath}, 1000ms}; RefactoringDatabaseInitializer databaseInitializer{database}; FilePathCaching filePathCache{database}; SymbolIndexing symbolIndexing{database, filePathCache};