From 12539f35e385c9250cd67e387c67dbaff4de34f3 Mon Sep 17 00:00:00 2001 From: Christian Mollekopf Date: Fri, 24 Apr 2015 10:41:11 +0200 Subject: Keep thread alive until the end of the query, and cleanup the resultSet. --- tests/clientapitest.cpp | 54 ++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 45 insertions(+), 9 deletions(-) (limited to 'tests') diff --git a/tests/clientapitest.cpp b/tests/clientapitest.cpp index 7bcd7b0..057495e 100644 --- a/tests/clientapitest.cpp +++ b/tests/clientapitest.cpp @@ -24,10 +24,11 @@ class DummyResourceFacade : public Akonadi2::StoreFacade create(const Akonadi2::ApplicationDomain::Event &domainObject){ return Async::null(); }; - virtual Async::Job modify(const Akonadi2::ApplicationDomain::Event &domainObject){ return Async::null(); }; - virtual Async::Job remove(const Akonadi2::ApplicationDomain::Event &domainObject){ return Async::null(); }; - virtual Async::Job load(const Akonadi2::Query &query, const std::function &resultCallback) + Async::Job create(const Akonadi2::ApplicationDomain::Event &domainObject) Q_DECL_OVERRIDE { return Async::null(); }; + Async::Job modify(const Akonadi2::ApplicationDomain::Event &domainObject) Q_DECL_OVERRIDE { return Async::null(); }; + Async::Job remove(const Akonadi2::ApplicationDomain::Event &domainObject) Q_DECL_OVERRIDE { return Async::null(); }; + + Async::Job load(const Akonadi2::Query &query, const std::function &resultCallback) { return Async::start([this, resultCallback](Async::Future &future) { qDebug() << "load called"; @@ -39,14 +40,23 @@ public: }); } - Async::Job load(const Akonadi2::Query &query, const QSharedPointer > &resultProvider) + Async::Job load(const Akonadi2::Query &query, const QSharedPointer > &resultProvider) Q_DECL_OVERRIDE { auto runner = QSharedPointer::create(query); //The runner only lives as long as the resultProvider resultProvider->setQueryRunner(runner); - runner->setQuery([this, resultProvider, query](qint64 oldRevision, qint64 newRevision) -> Async::Job { + QWeakPointer > weakResultProvider = resultProvider; + capturedResultProvider = resultProvider; + runner->setQuery([this, weakResultProvider, query](qint64 oldRevision, qint64 newRevision) -> Async::Job { qDebug() << "Creating query for revisions: " << oldRevision << newRevision; - return Async::start([this, resultProvider, query](Async::Future &future) { + return Async::start([this, weakResultProvider, query](Async::Future &future) { + auto resultProvider = weakResultProvider.toStrongRef(); + if (!resultProvider) { + Warning() << "Tried executing query after result provider is already gone"; + future.setError(0, QString()); + future.setFinished(); + return; + } //TODO only emit changes and don't replace everything resultProvider->clear(); //rerun query @@ -84,6 +94,7 @@ public: QList results; QSharedPointer notifier; + QWeakPointer > capturedResultProvider; }; class ClientAPITest : public QObject @@ -123,8 +134,8 @@ private Q_SLOTS: facade.results << QSharedPointer::create("resource", "id", 0, QSharedPointer()); Akonadi2::FacadeFactory::instance().registerFacade("dummyresource", - [&facade](bool &externallManage){ - externallManage = true; + [&facade](bool &externallyManaged){ + externallyManaged = true; return &facade; } ); @@ -145,6 +156,31 @@ private Q_SLOTS: QTRY_COMPARE(result.size(), 2); } + void testQueryLifetime() + { + DummyResourceFacade facade; + facade.results << QSharedPointer::create("resource", "id", 0, QSharedPointer()); + + Akonadi2::FacadeFactory::instance().registerFacade("dummyresource", + [&facade](bool &externallyManaged){ + externallyManaged = true; + return &facade; + } + ); + + Akonadi2::Query query; + query.resources << "dummyresource"; + query.liveQuery = true; + + { + async::SyncListResult result(Akonadi2::Store::load(query)); + result.exec(); + QCOMPARE(result.size(), 1); + } + //It's running in a separate thread, so we have to wait for a moment. + QTRY_VERIFY(!facade.capturedResultProvider); + } + }; QTEST_MAIN(ClientAPITest) -- cgit v1.2.3