From 4585641b8c732e2425506aa58b56071531b426dc Mon Sep 17 00:00:00 2001 From: Uwe Klotz Date: Mon, 19 Jun 2017 23:23:57 +0200 Subject: [PATCH 1/9] Don't try to read more frames than available ...even if SoundSources should limit the requested amount if needed. --- src/analyzer/analyzerqueue.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/analyzer/analyzerqueue.cpp b/src/analyzer/analyzerqueue.cpp index 6ef487513af..ba579fff326 100644 --- a/src/analyzer/analyzerqueue.cpp +++ b/src/analyzer/analyzerqueue.cpp @@ -197,7 +197,7 @@ bool AnalyzerQueue::doAnalysis(TrackPointer tio, mixxx::AudioSourcePointer pAudi const SINT framesRead = pAudioSource->readSampleFramesStereo( - kAnalysisFramesPerBlock, + framesToRead, &m_sampleBuffer); DEBUG_ASSERT(framesRead <= framesToRead); frameIndex += framesRead; From c0b7a50815706df9a1d382a4464d902044816bae Mon Sep 17 00:00:00 2001 From: Uwe Klotz Date: Tue, 20 Jun 2017 23:53:12 +0200 Subject: [PATCH 2/9] Add move assignment operator to DbConnectionPooler This allows to conditionally create a DbConnectionPooler within a nested scope. --- src/util/db/dbconnectionpooler.cpp | 7 +++++++ src/util/db/dbconnectionpooler.h | 3 ++- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/src/util/db/dbconnectionpooler.cpp b/src/util/db/dbconnectionpooler.cpp index 4eb35bb4678..7723f8f5302 100644 --- a/src/util/db/dbconnectionpooler.cpp +++ b/src/util/db/dbconnectionpooler.cpp @@ -28,4 +28,11 @@ DbConnectionPooler::~DbConnectionPooler() { } } +DbConnectionPooler& DbConnectionPooler::operator=(DbConnectionPooler&& other) { + m_pDbConnectionPool = std::move(other.m_pDbConnectionPool); + // Move assignment should transfer ownership by invalidating + // the other instance. + DEBUG_ASSERT(!other); +} + } // namespace mixxx diff --git a/src/util/db/dbconnectionpooler.h b/src/util/db/dbconnectionpooler.h index b9cd76a1b4a..d1d68889aca 100644 --- a/src/util/db/dbconnectionpooler.h +++ b/src/util/db/dbconnectionpooler.h @@ -32,10 +32,11 @@ class DbConnectionPooler final { return static_cast(m_pDbConnectionPool); } + DbConnectionPooler& operator=(DbConnectionPooler&& other); + private: DbConnectionPooler(const DbConnectionPooler&) = delete; DbConnectionPooler& operator=(const DbConnectionPooler&) = delete; - DbConnectionPooler& operator=(DbConnectionPooler&&) = delete; // Prevent heap allocation static void * operator new(std::size_t); From 337533855f09237b8a1e3551b32baa4a87a317b4 Mon Sep 17 00:00:00 2001 From: Uwe Klotz Date: Tue, 20 Jun 2017 23:53:19 +0200 Subject: [PATCH 3/9] Fix saving of waveform analysis in database The initialization of the AnalysisDao with the thread-local database connection was missing. The restricted design of the analyzer API required to move the AnalysisDao from AnalyzeWaveform to AnalyzerQueue. --- src/analyzer/analyzerqueue.cpp | 33 ++++++++++++++++++++++++------- src/analyzer/analyzerqueue.h | 3 +++ src/analyzer/analyzerwaveform.cpp | 13 ++++++------ src/analyzer/analyzerwaveform.h | 6 +++--- src/test/analyserwaveformtest.cpp | 4 +++- 5 files changed, 42 insertions(+), 17 deletions(-) diff --git a/src/analyzer/analyzerqueue.cpp b/src/analyzer/analyzerqueue.cpp index ba579fff326..6f25bbd1957 100644 --- a/src/analyzer/analyzerqueue.cpp +++ b/src/analyzer/analyzerqueue.cpp @@ -7,11 +7,13 @@ #include "analyzer/analyzergain.h" #include "analyzer/analyzerebur128.h" #include "analyzer/analyzerwaveform.h" +#include "library/dao/analysisdao.h" #include "mixer/playerinfo.h" #include "sources/soundsourceproxy.h" #include "track/track.h" #include "util/compatibility.h" #include "util/db/dbconnectionpooler.h" +#include "util/db/dbconnectionpooled.h" #include "util/event.h" #include "util/timer.h" #include "util/trace.h" @@ -51,7 +53,8 @@ AnalyzerQueue::AnalyzerQueue( m_queue_size(0) { if (mode != Mode::WithoutWaveform) { - m_pAnalyzers.push_back(std::make_unique(pConfig)); + m_pAnalysisDao = std::make_unique(pConfig); + m_pAnalyzers.push_back(std::make_unique(m_pAnalysisDao.get())); } m_pAnalyzers.push_back(std::make_unique(pConfig)); m_pAnalyzers.push_back(std::make_unique(pConfig)); @@ -299,12 +302,21 @@ void AnalyzerQueue::run() { } void AnalyzerQueue::execThread() { - const mixxx::DbConnectionPooler dbConnection(m_pDbConnectionPool); - if (!dbConnection) { - kLogger.warning() - << "Failed to open database connection for analyzer queue"; - kLogger.debug() << "Exiting thread"; - return; + mixxx::DbConnectionPooler dbConnectionPooler; + if (m_pAnalysisDao) { + // Only create/open a new database connection for when needed + // for storing waveform analyses + dbConnectionPooler = mixxx::DbConnectionPooler(m_pDbConnectionPool); + if (!dbConnectionPooler) { + kLogger.warning() + << "Failed to open database connection for analyzer queue thread"; + return; + } + // Use the newly created database connection for this thread + m_pAnalysisDao->initialize(mixxx::DbConnectionPooled(m_pDbConnectionPool)); + // The database connection is valid until dbConnectionPooler is destroyed + // when exiting the enclosing function scope. The pooler as the owner of + // the connection must not be destroyed now! } m_progressInfo.current_track.reset(); @@ -380,6 +392,13 @@ void AnalyzerQueue::execThread() { } emptyCheck(); } + + if (m_pAnalysisDao) { + // Invalidate reference to the thread-local database connection + // that will be closed soon. Not necessary, just in case ;) + m_pAnalysisDao->initialize(QSqlDatabase()); + } + emit(queueEmpty()); // emit in case of exit; } diff --git a/src/analyzer/analyzerqueue.h b/src/analyzer/analyzerqueue.h index b37341a61db..c6c62e97cf2 100644 --- a/src/analyzer/analyzerqueue.h +++ b/src/analyzer/analyzerqueue.h @@ -16,6 +16,7 @@ #include "util/memory.h" class Analyzer; +class AnalysisDao; class AnalyzerQueue : public QThread { Q_OBJECT @@ -60,6 +61,8 @@ class AnalyzerQueue : public QThread { mixxx::DbConnectionPoolPtr m_pDbConnectionPool; + std::unique_ptr m_pAnalysisDao; + typedef std::unique_ptr AnalyzerPtr; std::vector m_pAnalyzers; diff --git a/src/analyzer/analyzerwaveform.cpp b/src/analyzer/analyzerwaveform.cpp index 19fb2a8663e..eb90ba16274 100644 --- a/src/analyzer/analyzerwaveform.cpp +++ b/src/analyzer/analyzerwaveform.cpp @@ -16,14 +16,15 @@ mixxx::Logger kLogger("AnalyzerWaveform"); } // anonymous AnalyzerWaveform::AnalyzerWaveform( - const UserSettingsPointer& pConfig) : - m_analysisDao(pConfig), + AnalysisDao* pAnalysisDao) : + m_pAnalysisDao(pAnalysisDao), m_skipProcessing(false), m_waveformData(nullptr), m_waveformSummaryData(nullptr), m_stride(0, 0), m_currentStride(0), m_currentSummaryStride(0) { + DEBUG_ASSERT(m_pAnalysisDao); // mandatory m_filter[0] = 0; m_filter[1] = 0; m_filter[2] = 0; @@ -102,7 +103,7 @@ bool AnalyzerWaveform::isDisabledOrLoadStoredSuccess(TrackPointer tio) const { if (trackId.isValid() && (missingWaveform || missingWavesummary)) { QList analyses = - m_analysisDao.getAnalysesForTrack(trackId); + m_pAnalysisDao->getAnalysesForTrack(trackId); QListIterator it(analyses); while (it.hasNext()) { @@ -117,7 +118,7 @@ bool AnalyzerWaveform::isDisabledOrLoadStoredSuccess(TrackPointer tio) const { missingWaveform = false; } else if (vc != WaveformFactory::VC_KEEP) { // remove all other Analysis except that one we should keep - m_analysisDao.deleteAnalysis(analysis.analysisId); + m_pAnalysisDao->deleteAnalysis(analysis.analysisId); } } if (analysis.type == AnalysisDao::TYPE_WAVESUMMARY) { vc = WaveformFactory::waveformSummaryVersionToVersionClass(analysis.version); @@ -127,7 +128,7 @@ bool AnalyzerWaveform::isDisabledOrLoadStoredSuccess(TrackPointer tio) const { missingWavesummary = false; } else if (vc != WaveformFactory::VC_KEEP) { // remove all other Analysis except that one we should keep - m_analysisDao.deleteAnalysis(analysis.analysisId); + m_pAnalysisDao->deleteAnalysis(analysis.analysisId); } } } @@ -309,7 +310,7 @@ void AnalyzerWaveform::finalize(TrackPointer tio) { // waveforms (i.e. if the config setting was disabled in a previous scan) // and then it is not called. The other analyzers have signals which control // the update of their data. - m_analysisDao.saveTrackAnalyses(*tio); + m_pAnalysisDao->saveTrackAnalyses(*tio); kLogger.debug() << "Waveform generation for track" << tio->getId() << "done" << m_timer.elapsed().debugSecondsWithUnit(); diff --git a/src/analyzer/analyzerwaveform.h b/src/analyzer/analyzerwaveform.h index ccc4bdf7780..085194707da 100644 --- a/src/analyzer/analyzerwaveform.h +++ b/src/analyzer/analyzerwaveform.h @@ -7,7 +7,6 @@ #include "analyzer/analyzer.h" #include "waveform/waveform.h" -#include "library/dao/analysisdao.h" #include "util/math.h" #include "util/performancetimer.h" @@ -15,6 +14,7 @@ //#define TEST_HEAT_MAP class EngineFilterIIRBase; +class AnalysisDao; inline CSAMPLE scaleSignal(CSAMPLE invalue, FilterIndex index = FilterCount) { if (invalue == 0.0) { @@ -137,7 +137,7 @@ struct WaveformStride { class AnalyzerWaveform : public Analyzer { public: explicit AnalyzerWaveform( - const UserSettingsPointer& pConfig); + AnalysisDao* pAnalysisDao); ~AnalyzerWaveform() override; bool initialize(TrackPointer tio, int sampleRate, int totalSamples) override; @@ -154,7 +154,7 @@ class AnalyzerWaveform : public Analyzer { void destroyFilters(); void storeIfGreater(float* pDest, float source); - mutable AnalysisDao m_analysisDao; + AnalysisDao* m_pAnalysisDao; bool m_skipProcessing; diff --git a/src/test/analyserwaveformtest.cpp b/src/test/analyserwaveformtest.cpp index ad619b842fa..8e40121dbb8 100644 --- a/src/test/analyserwaveformtest.cpp +++ b/src/test/analyserwaveformtest.cpp @@ -18,7 +18,8 @@ namespace { class AnalyzerWaveformTest: public MixxxTest { protected: AnalyzerWaveformTest() - : aw(config()), + : analysisDao(config()), + aw(&analysisDao), bigbuf(nullptr), canaryBigBuf(nullptr) { } @@ -49,6 +50,7 @@ class AnalyzerWaveformTest: public MixxxTest { } protected: + AnalysisDao analysisDao; AnalyzerWaveform aw; TrackPointer tio; CSAMPLE* bigbuf; From f55f0757e56462fc93b580d8f294eb3506d0ec6e Mon Sep 17 00:00:00 2001 From: Uwe Klotz Date: Wed, 21 Jun 2017 07:22:35 +0200 Subject: [PATCH 4/9] Add missing return value in assignment operator --- src/util/db/dbconnectionpooler.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/util/db/dbconnectionpooler.cpp b/src/util/db/dbconnectionpooler.cpp index 7723f8f5302..51cffc5ba56 100644 --- a/src/util/db/dbconnectionpooler.cpp +++ b/src/util/db/dbconnectionpooler.cpp @@ -33,6 +33,7 @@ DbConnectionPooler& DbConnectionPooler::operator=(DbConnectionPooler&& other) { // Move assignment should transfer ownership by invalidating // the other instance. DEBUG_ASSERT(!other); + return *this; } } // namespace mixxx From d86694eb5a7ecfd6695ed2a7b12e1cc3e0ee0caa Mon Sep 17 00:00:00 2001 From: Uwe Klotz Date: Wed, 21 Jun 2017 22:57:04 +0200 Subject: [PATCH 5/9] Use default move assignment (if available) --- src/util/db/dbconnectionpooler.cpp | 8 -------- src/util/db/dbconnectionpooler.h | 10 +++++++++- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/util/db/dbconnectionpooler.cpp b/src/util/db/dbconnectionpooler.cpp index 51cffc5ba56..4eb35bb4678 100644 --- a/src/util/db/dbconnectionpooler.cpp +++ b/src/util/db/dbconnectionpooler.cpp @@ -28,12 +28,4 @@ DbConnectionPooler::~DbConnectionPooler() { } } -DbConnectionPooler& DbConnectionPooler::operator=(DbConnectionPooler&& other) { - m_pDbConnectionPool = std::move(other.m_pDbConnectionPool); - // Move assignment should transfer ownership by invalidating - // the other instance. - DEBUG_ASSERT(!other); - return *this; -} - } // namespace mixxx diff --git a/src/util/db/dbconnectionpooler.h b/src/util/db/dbconnectionpooler.h index d1d68889aca..71ed383394c 100644 --- a/src/util/db/dbconnectionpooler.h +++ b/src/util/db/dbconnectionpooler.h @@ -32,7 +32,15 @@ class DbConnectionPooler final { return static_cast(m_pDbConnectionPool); } - DbConnectionPooler& operator=(DbConnectionPooler&& other); +#if !defined(_MSC_VER) || _MSC_VER > 1900 + DbConnectionPooler& operator=(DbConnectionPooler&&) = default; +#else + // Workaround for Visual Studio 2015 (and before) + DbConnectionPooler& operator=(DbConnectionPooler&& other) { + m_pDbConnectionPool = std::move(other.m_pDbConnectionPool); + return *this; + } +#endif private: DbConnectionPooler(const DbConnectionPooler&) = delete; From 376164dae9d54521dd5b498f37e526ba44a0f000 Mon Sep 17 00:00:00 2001 From: Uwe Klotz Date: Wed, 21 Jun 2017 22:58:58 +0200 Subject: [PATCH 6/9] Explain usage of thread-local database connection --- src/analyzer/analyzerqueue.cpp | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/src/analyzer/analyzerqueue.cpp b/src/analyzer/analyzerqueue.cpp index 6f25bbd1957..99169da4740 100644 --- a/src/analyzer/analyzerqueue.cpp +++ b/src/analyzer/analyzerqueue.cpp @@ -302,21 +302,22 @@ void AnalyzerQueue::run() { } void AnalyzerQueue::execThread() { + // The thread-local database connection for waveform anylsis must not + // be closed before returning from this function. Therefore the + // DbConnectionPooler is defined at the outher function scope, + // independent of whether a database connection is opened or not. mixxx::DbConnectionPooler dbConnectionPooler; + // m_pAnalysisDao remains null if no analyzer needs database access. + // Currently only waveform analyses makes use of it. if (m_pAnalysisDao) { - // Only create/open a new database connection for when needed - // for storing waveform analyses dbConnectionPooler = mixxx::DbConnectionPooler(m_pDbConnectionPool); if (!dbConnectionPooler) { kLogger.warning() << "Failed to open database connection for analyzer queue thread"; return; } - // Use the newly created database connection for this thread + // Obtain and use the newly created database connection within this thread m_pAnalysisDao->initialize(mixxx::DbConnectionPooled(m_pDbConnectionPool)); - // The database connection is valid until dbConnectionPooler is destroyed - // when exiting the enclosing function scope. The pooler as the owner of - // the connection must not be destroyed now! } m_progressInfo.current_track.reset(); From 7d297aa607c8085b25871176f63898365fad4a7a Mon Sep 17 00:00:00 2001 From: Uwe Klotz Date: Wed, 21 Jun 2017 23:46:10 +0200 Subject: [PATCH 7/9] Fix some typos --- src/analyzer/analyzerqueue.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/analyzer/analyzerqueue.cpp b/src/analyzer/analyzerqueue.cpp index 99169da4740..ceba67a1241 100644 --- a/src/analyzer/analyzerqueue.cpp +++ b/src/analyzer/analyzerqueue.cpp @@ -302,10 +302,11 @@ void AnalyzerQueue::run() { } void AnalyzerQueue::execThread() { - // The thread-local database connection for waveform anylsis must not + // The thread-local database connection for waveform analysis must not // be closed before returning from this function. Therefore the - // DbConnectionPooler is defined at the outher function scope, - // independent of whether a database connection is opened or not. + // DbConnectionPooler is defined at this outer function scope, + // independent of whether a database connection will be opened + // or not. mixxx::DbConnectionPooler dbConnectionPooler; // m_pAnalysisDao remains null if no analyzer needs database access. // Currently only waveform analyses makes use of it. From 4aedce29dc78d4692f06489a95cf479cc7cb27be Mon Sep 17 00:00:00 2001 From: Uwe Klotz Date: Thu, 22 Jun 2017 07:38:49 +0200 Subject: [PATCH 8/9] Fix MSVC build (2015 and before) --- src/util/db/dbconnectionpooler.cpp | 3 ++- src/util/db/dbconnectionpooler.h | 14 ++++++++++---- 2 files changed, 12 insertions(+), 5 deletions(-) diff --git a/src/util/db/dbconnectionpooler.cpp b/src/util/db/dbconnectionpooler.cpp index 4eb35bb4678..6d222399979 100644 --- a/src/util/db/dbconnectionpooler.cpp +++ b/src/util/db/dbconnectionpooler.cpp @@ -15,7 +15,8 @@ DbConnectionPooler::DbConnectionPooler( DbConnectionPoolPtr pDbConnectionPool) { if (pDbConnectionPool && pDbConnectionPool->createThreadLocalConnection()) { // m_pDbConnectionPool indicates if the thread-local connection has actually - // been created during construction. Otherwise this instance is non-functional. + // been created during construction. Otherwise this instance does not store + // any reference to the connection pool and is non-functional. m_pDbConnectionPool = std::move(pDbConnectionPool); } } diff --git a/src/util/db/dbconnectionpooler.h b/src/util/db/dbconnectionpooler.h index 71ed383394c..c3229040e01 100644 --- a/src/util/db/dbconnectionpooler.h +++ b/src/util/db/dbconnectionpooler.h @@ -21,8 +21,15 @@ class DbConnectionPooler final { public: explicit DbConnectionPooler( DbConnectionPoolPtr pDbConnectionPool = DbConnectionPoolPtr()); - DbConnectionPooler( - DbConnectionPooler&& other) = default; + DbConnectionPooler(const DbConnectionPooler&) = delete; +#if !defined(_MSC_VER) || _MSC_VER > 1900 + DbConnectionPooler(DbConnectionPooler&&) = default; +#else + // Workaround for Visual Studio 2015 (and before) + DbConnectionPooler(DbConnectionPooler&& other) + : m_pDbConnectionPool(std::move(other.m_pDbConnectionPool)) { + } +#endif ~DbConnectionPooler(); // Checks if a thread-local connection has actually been created @@ -32,6 +39,7 @@ class DbConnectionPooler final { return static_cast(m_pDbConnectionPool); } + DbConnectionPooler& operator=(const DbConnectionPooler&) = delete; #if !defined(_MSC_VER) || _MSC_VER > 1900 DbConnectionPooler& operator=(DbConnectionPooler&&) = default; #else @@ -43,8 +51,6 @@ class DbConnectionPooler final { #endif private: - DbConnectionPooler(const DbConnectionPooler&) = delete; - DbConnectionPooler& operator=(const DbConnectionPooler&) = delete; // Prevent heap allocation static void * operator new(std::size_t); From 2ce4adbd09fb7a26f58d11b0a80a1d308486534d Mon Sep 17 00:00:00 2001 From: Uwe Klotz Date: Thu, 22 Jun 2017 07:39:16 +0200 Subject: [PATCH 9/9] Test move semantics of DbConnectionPooler --- src/analyzer/analyzerqueue.cpp | 10 ++++---- src/preferences/upgrade.cpp | 2 +- src/test/dbconnectionpool_test.cpp | 37 ++++++++++++++++++++++++++++++ src/util/db/dbconnectionpooler.h | 6 ++--- 4 files changed, 46 insertions(+), 9 deletions(-) create mode 100644 src/test/dbconnectionpool_test.cpp diff --git a/src/analyzer/analyzerqueue.cpp b/src/analyzer/analyzerqueue.cpp index ceba67a1241..26f7da95fcc 100644 --- a/src/analyzer/analyzerqueue.cpp +++ b/src/analyzer/analyzerqueue.cpp @@ -311,14 +311,16 @@ void AnalyzerQueue::execThread() { // m_pAnalysisDao remains null if no analyzer needs database access. // Currently only waveform analyses makes use of it. if (m_pAnalysisDao) { - dbConnectionPooler = mixxx::DbConnectionPooler(m_pDbConnectionPool); - if (!dbConnectionPooler) { + dbConnectionPooler = mixxx::DbConnectionPooler(m_pDbConnectionPool); // move assignment + if (!dbConnectionPooler.isPooling()) { kLogger.warning() - << "Failed to open database connection for analyzer queue thread"; + << "Failed to obtain database connection for analyzer queue thread"; return; } // Obtain and use the newly created database connection within this thread - m_pAnalysisDao->initialize(mixxx::DbConnectionPooled(m_pDbConnectionPool)); + QSqlDatabase dbConnection = mixxx::DbConnectionPooled(m_pDbConnectionPool); + DEBUG_ASSERT(dbConnection.isOpen()); + m_pAnalysisDao->initialize(dbConnection); } m_progressInfo.current_track.reset(); diff --git a/src/preferences/upgrade.cpp b/src/preferences/upgrade.cpp index c67d6ab6426..cc54f1d703f 100644 --- a/src/preferences/upgrade.cpp +++ b/src/preferences/upgrade.cpp @@ -366,7 +366,7 @@ UserSettingsPointer Upgrade::versionUpgrade(const QString& settingsPath) { MixxxDb mixxxDb(config); const mixxx::DbConnectionPooler dbConnectionPooler( mixxxDb.connectionPool()); - if (dbConnectionPooler) { + if (dbConnectionPooler.isPooling()) { QSqlDatabase dbConnection = mixxx::DbConnectionPooled(mixxxDb.connectionPool()); DEBUG_ASSERT(dbConnection.isOpen()); if (MixxxDb::initDatabaseSchema(dbConnection)) { diff --git a/src/test/dbconnectionpool_test.cpp b/src/test/dbconnectionpool_test.cpp new file mode 100644 index 00000000000..cfef128462f --- /dev/null +++ b/src/test/dbconnectionpool_test.cpp @@ -0,0 +1,37 @@ +#include + +#include "test/mixxxtest.h" + +#include "database/mixxxdb.h" +#include "util/db/dbconnectionpooler.h" +#include "util/db/dbconnectionpooled.h" + +#include "library/dao/settingsdao.h" + +#include "util/assert.h" + + +class DbConnectionPoolTest : public MixxxTest { + protected: + DbConnectionPoolTest() + : m_mixxxDb(config()) { + } + + protected: + const MixxxDb m_mixxxDb; +}; + +TEST_F(DbConnectionPoolTest, MoveSemantics) { + mixxx::DbConnectionPooler p1(m_mixxxDb.connectionPool()); + EXPECT_TRUE(p1.isPooling()); + + // Move construction + mixxx::DbConnectionPooler p2(std::move(p1)); + EXPECT_FALSE(p1.isPooling()); + EXPECT_TRUE(p2.isPooling()); + + // Move assignment + p1 = std::move(p2); + EXPECT_TRUE(p1.isPooling()); + EXPECT_FALSE(p2.isPooling()); +} diff --git a/src/util/db/dbconnectionpooler.h b/src/util/db/dbconnectionpooler.h index c3229040e01..f03956ce965 100644 --- a/src/util/db/dbconnectionpooler.h +++ b/src/util/db/dbconnectionpooler.h @@ -33,9 +33,8 @@ class DbConnectionPooler final { ~DbConnectionPooler(); // Checks if a thread-local connection has actually been created - // during construction. Otherwise this instance does not store - // any reference to the connection pool and is non-functional. - explicit operator bool() const { + // during construction and is owned by this instance. + bool isPooling() const { return static_cast(m_pDbConnectionPool); } @@ -51,7 +50,6 @@ class DbConnectionPooler final { #endif private: - // Prevent heap allocation static void * operator new(std::size_t); static void * operator new[](std::size_t);