From 9bb1f3434d3a727a66e2adee5caa50ef56c3960b Mon Sep 17 00:00:00 2001 From: Mark Liversedge Date: Fri, 14 Aug 2020 10:25:21 +0100 Subject: [PATCH] Fixup RideCache Load in Thread .. move thread based load of ridecache into ridecache, this fixes a serious regression. .. previously because the ridecache was created in a thread it could not attach to the events from the main gui event loop. .. we now load the RideDB.json file in a worker thread, but the ridecache, and its items are created in the main thread. --- src/Core/Athlete.cpp | 23 +++++++---------------- src/Core/Athlete.h | 13 ------------- src/Core/RideCache.cpp | 24 +++++++++++++++++++++++- src/Core/RideCache.h | 2 ++ 4 files changed, 32 insertions(+), 30 deletions(-) diff --git a/src/Core/Athlete.cpp b/src/Core/Athlete.cpp index e72815174..050fd52b6 100644 --- a/src/Core/Athlete.cpp +++ b/src/Core/Athlete.cpp @@ -177,23 +177,14 @@ Athlete::Athlete(Context *context, const QDir &homeDir) cloudAutoDownload = new CloudServiceAutoDownload(context); connect(context, SIGNAL(refreshEnd()), cloudAutoDownload, SLOT(autoDownload())); - // blocking as at startup - if (context->mainWindow->progress) { - // now most dependencies are in get cache - rideCache = new RideCache(context); - loadComplete(); - } else { - // load in background once GC is up and running - AthleteLoader *loader = new AthleteLoader(context); - connect(loader, SIGNAL(finished()), this, SLOT(loadComplete())); - loader->start(); - } -} + // now most dependencies are in get cache + QEventLoop loop; + rideCache = new RideCache(context); + connect(rideCache, SIGNAL(loadComplete()), &loop, SLOT(quit())); + connect(rideCache, SIGNAL(loadComplete()), this, SLOT(loadComplete())); -void -AthleteLoader::run() -{ - context->athlete->rideCache = new RideCache(context); + // we need to block on load complete if first (before mainwindow ready) + if (context->mainWindow->progress) loop.exec(); } void diff --git a/src/Core/Athlete.h b/src/Core/Athlete.h index c5a8035e6..3bf4134f8 100644 --- a/src/Core/Athlete.h +++ b/src/Core/Athlete.h @@ -225,17 +225,4 @@ class AthleteDirectoryStructure : public QObject { }; -class MainWindow; -class AthleteLoader : public QThread -{ - public: - - // load an athlete in background - AthleteLoader(Context *context) : context(context) {} - void run() override; - - private: - Context *context; -}; - #endif diff --git a/src/Core/RideCache.cpp b/src/Core/RideCache.cpp index 09a76737e..535753bb9 100644 --- a/src/Core/RideCache.cpp +++ b/src/Core/RideCache.cpp @@ -49,6 +49,18 @@ bool rideCacheGreaterThan(const RideItem *a, const RideItem *b) { return a->dateTime > b->dateTime; } bool rideCacheLessThan(const RideItem *a, const RideItem *b) { return a->dateTime < b->dateTime; } +class RideCacheLoader : public QThread +{ +public: + + RideCacheLoader(RideCache *cache) : cache(cache) {} + void run() { cache->load(); } + +private: + + RideCache *cache; +}; + RideCache::RideCache(Context *context) : context(context) { directory = context->athlete->home->activities(); @@ -128,8 +140,15 @@ RideCache::RideCache(Context *context) : context(context) qSort(rides_.begin(), rides_.end(), rideCacheLessThan); // load the store - will unstale once cache restored - load(); + RideCacheLoader *rideCacheLoader = new RideCacheLoader(this); + connect(rideCacheLoader, SIGNAL(finished()), this, SLOT(postLoad())); + connect(rideCacheLoader, SIGNAL(finished()), this, SIGNAL(loadComplete())); + rideCacheLoader->start(); +} +void +RideCache::postLoad() +{ // set model once we have the basics model_ = new RideCacheModel(context, this); @@ -461,6 +480,9 @@ RideCache::writeAsCSV(QString filename) void itemRefresh(RideItem *&item) { + // debugging below to watch refreshing take place + //fprintf(stderr, "%s %s refresh\n", item->context->athlete->cyclist.toStdString().c_str(), item->dateTime.toString().toStdString().c_str()); fflush(stderr); + // need parser to be reentrant !item->refresh(); if (item->isstale) { item->refresh(); diff --git a/src/Core/RideCache.h b/src/Core/RideCache.h index e167726f3..f07a2cec0 100644 --- a/src/Core/RideCache.h +++ b/src/Core/RideCache.h @@ -100,6 +100,7 @@ class RideCache : public QObject // restore / dump cache to disk (json) void load(); + void postLoad(); void save(bool opendata=false, QString filename=""); // find entry quickly @@ -126,6 +127,7 @@ class RideCache : public QObject signals: void modelProgress(int, int); // let others know when we're refreshing the model estimates + void loadComplete(); // when loading the cache completes... // us telling the world the item changed void itemChanged(RideItem*);