[Pkg-running-devel] [openambit] 09/23: Separate movescount handling to separate thread completely. It is ugly, but it works, should be cleaned up sometime... Fixes #30

Christian Perrier bubulle at moszumanska.debian.org
Sat Jul 1 19:36:27 UTC 2017


This is an automated email from the git hooks/post-receive script.

bubulle pushed a commit to branch master
in repository openambit.

commit ecd24c81077733e33e93399d979fd4b572b28ed7
Author: Emil Ljungdahl <emil at kratern.se>
Date:   Fri Sep 12 21:05:50 2014 +0200

    Separate movescount handling to separate thread completely. It is ugly, but it works, should be cleaned up sometime...
    Fixes #30
---
 src/openambit/mainwindow.cpp                      |   5 +-
 src/openambit/movescount/CMakeLists.txt           |   2 +
 src/openambit/movescount/movescount.cpp           | 264 +++++++++++++---------
 src/openambit/movescount/movescount.h             |  31 ++-
 src/openambit/movescount/movescountlogchecker.cpp | 107 +++++++++
 src/openambit/movescount/movescountlogchecker.h   |  32 +++
 6 files changed, 323 insertions(+), 118 deletions(-)

diff --git a/src/openambit/mainwindow.cpp b/src/openambit/mainwindow.cpp
index 38a3caf..d170aeb 100644
--- a/src/openambit/mainwindow.cpp
+++ b/src/openambit/mainwindow.cpp
@@ -119,9 +119,12 @@ MainWindow::~MainWindow()
 {
     deviceWorkerThread.quit();
     deviceWorkerThread.wait();
-
     delete deviceManager;
 
+    if (movesCount != NULL) {
+        movesCount->exit();
+    }
+
     delete trayIcon;
     delete trayIconMinimizeRestoreAction;
     delete trayIconSyncAction;
diff --git a/src/openambit/movescount/CMakeLists.txt b/src/openambit/movescount/CMakeLists.txt
index 95b2947..c0a8c32 100644
--- a/src/openambit/movescount/CMakeLists.txt
+++ b/src/openambit/movescount/CMakeLists.txt
@@ -4,6 +4,7 @@ set ( openambit_SRCS
   ${CMAKE_CURRENT_SOURCE_DIR}/movescountjson.cpp
   ${CMAKE_CURRENT_SOURCE_DIR}/movescountlogdirentry.cpp
   ${CMAKE_CURRENT_SOURCE_DIR}/movescountxml.cpp
+  ${CMAKE_CURRENT_SOURCE_DIR}/movescountlogchecker.cpp
   PARENT_SCOPE
 )
 
@@ -13,5 +14,6 @@ set ( openambit_MOCS
   ${CMAKE_CURRENT_SOURCE_DIR}/movescountjson.h
   ${CMAKE_CURRENT_SOURCE_DIR}/movescountlogdirentry.h
   ${CMAKE_CURRENT_SOURCE_DIR}/movescountxml.h
+  ${CMAKE_CURRENT_SOURCE_DIR}/movescountlogchecker.h
   PARENT_SCOPE
 )
diff --git a/src/openambit/movescount/movescount.cpp b/src/openambit/movescount/movescount.cpp
index 6d85a8f..94d3016 100644
--- a/src/openambit/movescount/movescount.cpp
+++ b/src/openambit/movescount/movescount.cpp
@@ -47,6 +47,24 @@ MovesCount* MovesCount::instance()
     return m_Instance;
 }
 
+void MovesCount::exit()
+{
+    static QMutex mutex;
+
+    exiting = true;
+
+    mutex.lock();
+    if (m_Instance) {
+        workerThread.quit();
+        workerThread.wait();
+
+        delete logChecker;
+
+        m_Instance = NULL;
+    }
+    mutex.unlock();
+}
+
 void MovesCount::setBaseAddress(QString baseAddress)
 {
     this->baseAddress = baseAddress;
@@ -97,6 +115,134 @@ bool MovesCount::isAuthorized()
 int MovesCount::getOrbitalData(u_int8_t **data)
 {
     int ret = -1;
+
+    if (&workerThread == QThread::currentThread()) {
+        ret = getOrbitalDataInThread(data);
+    }
+    else {
+        QMetaObject::invokeMethod(this, "getOrbitalDataInThread", Qt::BlockingQueuedConnection,
+                                  Q_RETURN_ARG(int, ret),
+                                  Q_ARG(u_int8_t **, data));
+    }
+
+    return ret;
+}
+
+int MovesCount::getPersonalSettings(ambit_personal_settings_t *settings)
+{
+    int ret = -1;
+
+    if (&workerThread == QThread::currentThread()) {
+        ret = getPersonalSettingsInThread(settings);
+    }
+    else {
+        QMetaObject::invokeMethod(this, "getPersonalSettingsInThread", Qt::BlockingQueuedConnection,
+                                  Q_RETURN_ARG(int, ret),
+                                  Q_ARG(ambit_personal_settings_t *, settings));
+    }
+
+    return ret;
+}
+
+void MovesCount::getDeviceSettings()
+{
+    QMetaObject::invokeMethod(this, "getDeviceSettingsInThread", Qt::AutoConnection);
+}
+
+QList<MovesCountLogDirEntry> MovesCount::getMovescountEntries(QDate startTime, QDate endTime)
+{
+    QList<MovesCountLogDirEntry> retList;
+
+    if (&workerThread == QThread::currentThread()) {
+        retList = getMovescountEntriesInThread(startTime, endTime);
+    }
+    else {
+        QMetaObject::invokeMethod(this, "getMovescountEntriesInThread", Qt::BlockingQueuedConnection,
+                                  Q_RETURN_ARG(QList<MovesCountLogDirEntry>, retList),
+                                  Q_ARG(QDate, startTime),
+                                  Q_ARG(QDate, endTime));
+    }
+
+    return retList;
+}
+
+void MovesCount::checkAuthorization()
+{
+    QMetaObject::invokeMethod(this, "checkAuthorizationInThread", Qt::AutoConnection);
+}
+
+void MovesCount::checkLatestFirmwareVersion()
+{
+    QMetaObject::invokeMethod(this, "checkLatestFirmwareVersionInThread", Qt::AutoConnection);
+}
+
+void MovesCount::writePersonalSettings(ambit_personal_settings_t *settings)
+{
+    if (&workerThread == QThread::currentThread()) {
+        writePersonalSettingsInThread(settings);
+    }
+    else {
+        QMetaObject::invokeMethod(this, "writePersonalSettingsInThread", Qt::BlockingQueuedConnection,
+                                  Q_ARG(ambit_personal_settings_t *, settings));
+    }
+}
+
+void MovesCount::writeLog(LogEntry *logEntry)
+{
+    if (&workerThread == QThread::currentThread()) {
+        writeLogInThread(logEntry);
+    }
+    else {
+        QMetaObject::invokeMethod(this, "writeLogInThread", Qt::BlockingQueuedConnection,
+                                  Q_ARG(LogEntry *, logEntry));
+    }
+}
+
+void MovesCount::authCheckFinished()
+{
+    if (authCheckReply != NULL) {
+        checkReplyAuthorization(authCheckReply);
+        authCheckReply->deleteLater();
+        authCheckReply = NULL;
+    }
+}
+
+void MovesCount::firmwareReplyFinished()
+{
+    u_int8_t fw_version[4];
+
+    if (firmwareCheckReply != NULL) {
+        if (firmwareCheckReply->error() == QNetworkReply::NoError) {
+            QByteArray data = firmwareCheckReply->readAll();
+            if (jsonParser.parseFirmwareVersionReply(data, fw_version) == 0) {
+                if (fw_version[0] > device_info.fw_version[0] ||
+                    (fw_version[0] == device_info.fw_version[0] && (fw_version[1] > device_info.fw_version[1] ||
+                     (fw_version[1] == device_info.fw_version[1] && ((fw_version[2] | (fw_version[3] << 8)) > (device_info.fw_version[2] | (device_info.fw_version[3] << 8))))))) {
+                    emit newerFirmwareExists(QByteArray((const char*)fw_version, 4));
+                }
+            }
+        }
+
+        firmwareCheckReply->deleteLater();
+        firmwareCheckReply = NULL;
+    }
+}
+
+void MovesCount::recheckAuthorization()
+{
+    getDeviceSettings();
+}
+
+void MovesCount::handleAuthorizationSignal(bool authorized)
+{
+    if (authorized) {
+        logChecker->run();
+    }
+}
+
+int MovesCount::getOrbitalDataInThread(u_int8_t **data)
+{
+    int ret = -1;
     QNetworkReply *reply;
 
     reply = syncGET("/devices/gpsorbit/binary", "", false);
@@ -118,13 +264,13 @@ int MovesCount::getOrbitalData(u_int8_t **data)
     return ret;
 }
 
-int MovesCount::getPersonalSettings(ambit_personal_settings_t *settings)
+int MovesCount::getPersonalSettingsInThread(ambit_personal_settings_t *settings)
 {
     Q_UNUSED(settings);
     return 0;
 }
 
-int MovesCount::getDeviceSettings()
+void MovesCount::getDeviceSettingsInThread()
 {
     QNetworkReply *reply;
 
@@ -132,14 +278,10 @@ int MovesCount::getDeviceSettings()
 
     if (checkReplyAuthorization(reply)) {
         QByteArray _data = reply->readAll();
-
-        return 0;
     }
-
-    return -1;
 }
 
-QList<MovesCountLogDirEntry> MovesCount::getMovescountEntries(QDate startTime, QDate endTime)
+QList<MovesCountLogDirEntry> MovesCount::getMovescountEntriesInThread(QDate startTime, QDate endTime)
 {
     QNetworkReply *reply;
     QList<MovesCountLogDirEntry> retList;
@@ -158,7 +300,7 @@ QList<MovesCountLogDirEntry> MovesCount::getMovescountEntries(QDate startTime, Q
     return retList;
 }
 
-void MovesCount::checkAuthorization()
+void MovesCount::checkAuthorizationInThread()
 {
     if (authCheckReply == NULL) {
         authCheckReply = asyncGET("/members/private", "", true);
@@ -166,7 +308,7 @@ void MovesCount::checkAuthorization()
     }
 }
 
-void MovesCount::checkLatestFirmwareVersion()
+void MovesCount::checkLatestFirmwareVersionInThread()
 {
     if (firmwareCheckReply == NULL) {
         firmwareCheckReply = asyncGET("/devices/" + QString("%1/%2.%3.%4")
@@ -178,12 +320,12 @@ void MovesCount::checkLatestFirmwareVersion()
     }
 }
 
-void MovesCount::writePersonalSettings(ambit_personal_settings_t *settings)
+void MovesCount::writePersonalSettingsInThread(ambit_personal_settings_t *settings)
 {
     Q_UNUSED(settings);
 }
 
-void MovesCount::writeLog(LogEntry *logEntry)
+void MovesCount::writeLogInThread(LogEntry *logEntry)
 {
     QByteArray output;
     QNetworkReply *reply;
@@ -204,53 +346,13 @@ void MovesCount::writeLog(LogEntry *logEntry)
     }
 }
 
-void MovesCount::authCheckFinished()
-{
-    if (authCheckReply != NULL) {
-        checkReplyAuthorization(authCheckReply);
-        authCheckReply->deleteLater();
-        authCheckReply = NULL;
-    }
-}
-
-void MovesCount::firmwareReplyFinished()
-{
-    u_int8_t fw_version[4];
-
-    if (firmwareCheckReply != NULL) {
-        if (firmwareCheckReply->error() == QNetworkReply::NoError) {
-            QByteArray data = firmwareCheckReply->readAll();
-            if (jsonParser.parseFirmwareVersionReply(data, fw_version) == 0) {
-                if (fw_version[0] > device_info.fw_version[0] ||
-                    (fw_version[0] == device_info.fw_version[0] && (fw_version[1] > device_info.fw_version[1] ||
-                     (fw_version[1] == device_info.fw_version[1] && ((fw_version[2] | (fw_version[3] << 8)) > (device_info.fw_version[2] | (device_info.fw_version[3] << 8))))))) {
-                    emit newerFirmwareExists(QByteArray((const char*)fw_version, 4));
-                }
-            }
-        }
-
-        firmwareCheckReply->deleteLater();
-        firmwareCheckReply = NULL;
-    }
-}
-
-void MovesCount::recheckAuthorization()
-{
-    getDeviceSettings();
-}
-
-void MovesCount::handleAuthorizationSignal(bool authorized)
-{
-    if (authorized) {
-        checkUploadedLogs();
-    }
-}
-
 MovesCount::MovesCount() :
-    authorized(false), uploadedCheckRunning(false), firmwareCheckReply(NULL), authCheckReply(NULL)
+    exiting(false), authorized(false), firmwareCheckReply(NULL), authCheckReply(NULL)
 {
     this->manager = new QNetworkAccessManager(this);
 
+    this->logChecker = new MovesCountLogChecker();
+
     this->moveToThread(&workerThread);
     workerThread.start();
 
@@ -278,60 +380,6 @@ bool MovesCount::checkReplyAuthorization(QNetworkReply *reply)
     return authorized;
 }
 
-void MovesCount::checkUploadedLogs()
-{
-    QDateTime firstUnknown = QDateTime::currentDateTime();
-    QDateTime lastUnknown = QDateTime::fromTime_t(0);
-    QList<LogEntry*> missingEntries;
-
-    if (!uploadedCheckRunning) {
-        uploadedCheckRunning = true;
-
-        QList<LogStore::LogDirEntry> entries = logStore.dir();
-        foreach(LogStore::LogDirEntry entry, entries) {
-            LogEntry *logEntry = logStore.read(entry);
-            if (logEntry != NULL) {
-                if (logEntry->movescountId.length() == 0) {
-                    missingEntries.append(logEntry);
-                    if (logEntry->time < firstUnknown) {
-                        firstUnknown = logEntry->time;
-                    }
-                    if (logEntry->time > lastUnknown) {
-                        lastUnknown = logEntry->time;
-                    }
-                }
-                else {
-                    delete logEntry;
-                }
-            }
-        }
-
-        if (missingEntries.count() > 0) {
-            QList<MovesCountLogDirEntry> movescountEntries = getMovescountEntries(firstUnknown.date(), lastUnknown.date());
-            foreach(MovesCountLogDirEntry entry, movescountEntries) {
-                foreach(LogEntry *logEntry, missingEntries) {
-                    if (entry.time == logEntry->time) {
-                        missingEntries.removeOne(logEntry);
-                        logStore.storeMovescountId(logEntry->device, logEntry->time, entry.moveId);
-                        delete logEntry;
-                        break;
-                    }
-                }
-            }
-
-            // Delete remaining entries
-            while (missingEntries.count() > 0) {
-                LogEntry *logEntry = missingEntries.first();
-                writeLog(logEntry);
-                missingEntries.removeOne(logEntry);
-                delete logEntry;
-            }
-        }
-
-        uploadedCheckRunning = false;
-    }
-}
-
 QNetworkReply *MovesCount::asyncGET(QString path, QString additionalHeaders, bool auth)
 {
     QNetworkRequest req;
diff --git a/src/openambit/movescount/movescount.h b/src/openambit/movescount/movescount.h
index 045481b..456a2a3 100644
--- a/src/openambit/movescount/movescount.h
+++ b/src/openambit/movescount/movescount.h
@@ -35,12 +35,14 @@
 #include "logstore.h"
 #include "movescountjson.h"
 #include "movescountlogdirentry.h"
+#include "movescountlogchecker.h"
 
 class MovesCount : public QObject
 {
     Q_OBJECT
 public:
     static MovesCount* instance();
+    void exit();
 
     void setBaseAddress(QString baseAddress);
     void setAppkey(QString appkey);
@@ -52,31 +54,40 @@ public:
     bool isAuthorized();
     int getOrbitalData(u_int8_t **data);
     int getPersonalSettings(ambit_personal_settings_t *settings);
-    int getDeviceSettings();
+    void getDeviceSettings();
     QList<MovesCountLogDirEntry> getMovescountEntries(QDate startTime, QDate endTime);
-signals:
-    void newerFirmwareExists(QByteArray fw_version);
-    void movesCountAuth(bool authorized);
-    void logMoveID(QString device, QDateTime time, QString moveID);
-    
-public slots:
+
     void checkAuthorization();
     void checkLatestFirmwareVersion();
     void writePersonalSettings(ambit_personal_settings_t *settings);
     void writeLog(LogEntry *logEntry);
 
+signals:
+    void newerFirmwareExists(QByteArray fw_version);
+    void movesCountAuth(bool authorized);
+    void logMoveID(QString device, QDateTime time, QString moveID);
+
 private slots:
     void authCheckFinished();
     void firmwareReplyFinished();
     void recheckAuthorization();
     void handleAuthorizationSignal(bool authorized);
 
+    int getOrbitalDataInThread(u_int8_t **data);
+    int getPersonalSettingsInThread(ambit_personal_settings_t *settings);
+    void getDeviceSettingsInThread();
+    QList<MovesCountLogDirEntry> getMovescountEntriesInThread(QDate startTime, QDate endTime);
+
+    void checkAuthorizationInThread();
+    void checkLatestFirmwareVersionInThread();
+    void writePersonalSettingsInThread(ambit_personal_settings_t *settings);
+    void writeLogInThread(LogEntry *logEntry);
+
 private:
     MovesCount();
     ~MovesCount();
 
     bool checkReplyAuthorization(QNetworkReply *reply);
-    void checkUploadedLogs();
 
     QNetworkReply *asyncGET(QString path, QString additionalHeaders, bool auth);
     QNetworkReply *syncGET(QString path, QString additionalHeaders, bool auth);
@@ -84,8 +95,8 @@ private:
     QNetworkReply *asyncPOST(QString path, QString additionalHeaders, QByteArray &postData, bool auth);
     QNetworkReply *syncPOST(QString path, QString additionalHeaders, QByteArray &postData, bool auth);
 
+    bool exiting;
     bool authorized;
-    bool uploadedCheckRunning;
 
     QString baseAddress;
     QString appkey;
@@ -103,6 +114,8 @@ private:
 
     LogStore logStore;
 
+    MovesCountLogChecker *logChecker;
+
     QThread workerThread;
 };
 
diff --git a/src/openambit/movescount/movescountlogchecker.cpp b/src/openambit/movescount/movescountlogchecker.cpp
new file mode 100644
index 0000000..57e54f6
--- /dev/null
+++ b/src/openambit/movescount/movescountlogchecker.cpp
@@ -0,0 +1,107 @@
+#include "movescountlogchecker.h"
+#include "movescount.h"
+
+MovesCountLogChecker::MovesCountLogChecker(QObject *parent) :
+    QObject(parent), running(false), cancelRun(false)
+{
+    this->moveToThread(&workerThread);
+    workerThread.start();
+}
+
+MovesCountLogChecker::~MovesCountLogChecker()
+{
+    cancel();
+    workerThread.exit();
+    workerThread.wait();
+}
+
+void MovesCountLogChecker::run()
+{
+    if (!running) {
+        QMetaObject::invokeMethod(this, "checkUploadedLogs", Qt::AutoConnection);
+    }
+}
+
+bool MovesCountLogChecker::isRunning()
+{
+    return running;
+}
+
+void MovesCountLogChecker::cancel()
+{
+    cancelRun = true;
+}
+
+void MovesCountLogChecker::checkUploadedLogs()
+{
+    QDateTime firstUnknown = QDateTime::currentDateTime();
+    QDateTime lastUnknown = QDateTime::fromTime_t(0);
+    QList<LogEntry*> missingEntries;
+    MovesCount *movescount = MovesCount::instance();
+
+    running = true;
+
+    QList<LogStore::LogDirEntry> entries = logStore.dir();
+    foreach(LogStore::LogDirEntry entry, entries) {
+        // This is a long operation, exit if application want to quit
+        if (cancelRun) {
+            cancelRun = false;
+            return;
+        }
+        LogEntry *logEntry = logStore.read(entry);
+        if (logEntry != NULL) {
+            if (logEntry->movescountId.length() == 0) {
+                missingEntries.append(logEntry);
+                if (logEntry->time < firstUnknown) {
+                    firstUnknown = logEntry->time;
+                }
+                if (logEntry->time > lastUnknown) {
+                    lastUnknown = logEntry->time;
+                }
+            }
+            else {
+                delete logEntry;
+            }
+        }
+    }
+
+    if (missingEntries.count() > 0) {
+        // This is a long operation, exit if application want to quit
+        if (cancelRun) {
+            cancelRun = false;
+            return;
+        }
+        QList<MovesCountLogDirEntry> movescountEntries = movescount->getMovescountEntries(firstUnknown.date(), lastUnknown.date());
+        foreach(MovesCountLogDirEntry entry, movescountEntries) {
+            // This is a long operation, exit if application want to quit
+            if (cancelRun) {
+                cancelRun = false;
+                return;
+            }
+            foreach(LogEntry *logEntry, missingEntries) {
+                if (entry.time == logEntry->time) {
+                    missingEntries.removeOne(logEntry);
+                    logStore.storeMovescountId(logEntry->device, logEntry->time, entry.moveId);
+                    delete logEntry;
+                    break;
+                }
+            }
+        }
+
+        // Delete remaining entries
+        while (missingEntries.count() > 0) {
+            // This is a long operation, exit if application want to quit
+            if (cancelRun) {
+                cancelRun = false;
+                return;
+            }
+            LogEntry *logEntry = missingEntries.first();
+            movescount->writeLog(logEntry);
+            missingEntries.removeOne(logEntry);
+            delete logEntry;
+        }
+    }
+
+    cancelRun = false;
+    running = false;
+}
diff --git a/src/openambit/movescount/movescountlogchecker.h b/src/openambit/movescount/movescountlogchecker.h
new file mode 100644
index 0000000..213dc71
--- /dev/null
+++ b/src/openambit/movescount/movescountlogchecker.h
@@ -0,0 +1,32 @@
+#ifndef MOVESCOUNTLOGCHECKER_H
+#define MOVESCOUNTLOGCHECKER_H
+
+#include <QObject>
+#include <QThread>
+
+#include <libambit.h>
+
+#include "logentry.h"
+#include "logstore.h"
+
+class MovesCountLogChecker : public QObject
+{
+    Q_OBJECT
+public:
+    explicit MovesCountLogChecker(QObject *parent = 0);
+    ~MovesCountLogChecker();
+    void run();
+    bool isRunning();
+    void cancel();
+private slots:
+    void checkUploadedLogs();
+
+private:
+    bool running;
+    bool cancelRun;
+
+    LogStore logStore;
+    QThread workerThread;
+};
+
+#endif // MOVESCOUNTLOGCHECKER_H

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-running/openambit.git



More information about the Pkg-running-devel mailing list