Index: main.cpp =================================================================== diff -u -rfeb3423b373dc2a2c4267ef9fcb4d924d738423d -r5e78f0799b46963feb5756decb1a27b952cd19b3 --- main.cpp (.../main.cpp) (revision feb3423b373dc2a2c4267ef9fcb4d924d738423d) +++ main.cpp (.../main.cpp) (revision 5e78f0799b46963feb5756decb1a27b952cd19b3) @@ -91,17 +91,14 @@ app.installTranslator(&translator); } - //! - Initializing USB Watcher - _USBWatcher->init(); - - //! - Initializing File Handler - _FileHandler->init(); - //! - Initializing Logger - _Logger->init(); + _Logger.init(); LOG_EVENT(QObject::tr("Application Started")); + //! - Initializing USB Watcher + _USBWatcher.init(); + //! - Initializing Main Timer _MainTimer->init(); Index: sources/applicationcontroller.cpp =================================================================== diff -u -rfeb3423b373dc2a2c4267ef9fcb4d924d738423d -r5e78f0799b46963feb5756decb1a27b952cd19b3 --- sources/applicationcontroller.cpp (.../applicationcontroller.cpp) (revision feb3423b373dc2a2c4267ef9fcb4d924d738423d) +++ sources/applicationcontroller.cpp (.../applicationcontroller.cpp) (revision 5e78f0799b46963feb5756decb1a27b952cd19b3) @@ -22,6 +22,7 @@ #include "messagedispatcher.h" #include "logger.h" #include "usbwatcher.h" +#include "filehandler.h" // Singleton SINGLETON_INIT(ApplicationController) @@ -64,9 +65,9 @@ connect(_GuiController , SIGNAL(didUSBDriveUmount()), this , SLOT( onUSBDriveUmount())); - connect(_USBWatcher , SIGNAL(didUSBDriveMount ()), + connect(&_USBWatcher , SIGNAL(didUSBDriveMount ()), this , SLOT( onUSBDriveMount ())); - connect(_USBWatcher , SIGNAL(didUSBDriveRemove()), + connect(&_USBWatcher , SIGNAL(didUSBDriveRemove()), this , SLOT( onUSBDriveRemove())); connect(_GuiController , SIGNAL(didExportLog()), @@ -124,6 +125,8 @@ void ApplicationController::onExportLog() { + Storage::FileHandler fh; + fh.exportLog(); emit didExportLog(); } Index: sources/applicationcontroller.h =================================================================== diff -u -rfeb3423b373dc2a2c4267ef9fcb4d924d738423d -r5e78f0799b46963feb5756decb1a27b952cd19b3 --- sources/applicationcontroller.h (.../applicationcontroller.h) (revision feb3423b373dc2a2c4267ef9fcb4d924d738423d) +++ sources/applicationcontroller.h (.../applicationcontroller.h) (revision 5e78f0799b46963feb5756decb1a27b952cd19b3) @@ -20,7 +20,6 @@ // Project #include "main.h" #include "guiglobals.h" -#include "filehandler.h" #include "applicationpost.h" #include "caninterface.h" @@ -29,7 +28,6 @@ #define _ApplicationController ApplicationController::I() // namespace -using namespace Storage; using namespace Gui; using namespace Can; Index: sources/main.h =================================================================== diff -u -r5963f00ffd2c557d3ae06a5deea05032a3a3bd68 -r5e78f0799b46963feb5756decb1a27b952cd19b3 --- sources/main.h (.../main.h) (revision 5963f00ffd2c557d3ae06a5deea05032a3a3bd68) +++ sources/main.h (.../main.h) (revision 5e78f0799b46963feb5756decb1a27b952cd19b3) @@ -41,3 +41,19 @@ #define SINGLETON_INIT(vCLASS) \ vCLASS *vCLASS::_instance = nullptr; + + +#define SINGLETON(vCLASS) \ +private: \ + explicit vCLASS(QObject *parent = nullptr); \ + virtual ~vCLASS() { } \ + vCLASS(vCLASS const &) = delete; \ + vCLASS & operator = (vCLASS const &) = delete; \ +public: \ + static vCLASS &I() { \ + static vCLASS _instance; \ + return _instance; \ + } + + +#define PRINT_THREAD_NAME //qDebug() << __func__ << QThread::currentThread()->objectName() Index: sources/storage/filehandler.cpp =================================================================== diff -u -rfeb3423b373dc2a2c4267ef9fcb4d924d738423d -r5e78f0799b46963feb5756decb1a27b952cd19b3 --- sources/storage/filehandler.cpp (.../filehandler.cpp) (revision feb3423b373dc2a2c4267ef9fcb4d924d738423d) +++ sources/storage/filehandler.cpp (.../filehandler.cpp) (revision 5e78f0799b46963feb5756decb1a27b952cd19b3) @@ -14,47 +14,26 @@ #include "filehandler.h" //Qt -#include #include #include +#include +#include // Project #include "storageglobals.h" -#include "usbwatcher.h" -#include "applicationcontroller.h" +#include "logger.h" // namespace using namespace Storage; -// Singleton -SINGLETON_INIT(FileHandler) - -FileHandler::FileHandler(QObject *parent) : QObject(parent) { } - -bool FileHandler::init() -{ - initConnections(); - return true; -} - -void FileHandler::quit() -{ -} - -void FileHandler::initConnections() -{ - connect(_ApplicationController, SIGNAL(didExportLog()), - this , SLOT( onExportLog())); -} - bool FileHandler::write(const QString &vFileName, const QString &vContent, bool vAppend) { QFile file(vFileName); QIODevice::OpenMode openMode = vAppend ? QFile::Text | QFile::Append : QFile::Text | QFile::WriteOnly; if (! file.open(openMode)) { - qDebug() << "ERROR :" << tr("Can't open file for write (%1)").arg(vFileName); + LOG_ERROR(QObject::tr("Can't open file for write (%1)").arg(vFileName)); return false; } QTextStream out(&file); @@ -67,42 +46,30 @@ { QFile file(vFileName); if (! file.open(QFile::Text | QFile::ReadOnly)) { - qDebug() << "ERROR :" << tr("Can't open file for read (%1)").arg(vFileName); + LOG_ERROR(QObject::tr("Can't open file for read (%1)").arg(vFileName)); return false; } QTextStream in(&file); vContent = in.readAll(); return true; } - -bool FileHandler::onWrite(const QString &vFileName, const QString &vContent, bool vAppend) +int FileHandler::copyFolder(const QString &vSource, const QString &vDestination ) { - bool ok = write(vFileName, vContent, vAppend); - if (ok) { - emit didWrite(vFileName); - } - return ok; -} + PRINT_THREAD_NAME; -bool FileHandler::onRead(const QString &vFileName) -{ - QString mContent; - bool ok = read(vFileName, mContent); - if (ok) { - emit didRead(vFileName, mContent); - } - return ok; -} - -bool FileHandler::onExportLog() -{ - QString vSource = Storage::Log_Base_Path_Name_Location; - QString vDestination = Storage::USB_Mount_Point; - QString cp = "cp"; QStringList arguments; arguments << "-r" << vSource << vDestination; - _processCopyFolder.start(cp, arguments); - return true; + return QProcess::execute(cp, arguments); } + +bool FileHandler::exportLog() +{ + QString mSource = Storage::Log_Base_Path_Name_Location; + QString mDestination = Storage::USB_Mount_Point; + //QFuture future = + QtConcurrent::run(this, &FileHandler::copyFolder, mSource, mDestination); + //return future.result(); + return 0; +} Index: sources/storage/filehandler.h =================================================================== diff -u -rfeb3423b373dc2a2c4267ef9fcb4d924d738423d -r5e78f0799b46963feb5756decb1a27b952cd19b3 --- sources/storage/filehandler.h (.../filehandler.h) (revision feb3423b373dc2a2c4267ef9fcb4d924d738423d) +++ sources/storage/filehandler.h (.../filehandler.h) (revision 5e78f0799b46963feb5756decb1a27b952cd19b3) @@ -14,45 +14,20 @@ #pragma once // Qt -#include -#include +#include -// Project -#include "main.h" - -// Define -#define _FileHandler FileHandler::I() - namespace Storage { -class FileHandler : public QObject +class FileHandler { - Q_OBJECT - QProcess _processCopyFolder; + int copyFolder(const QString &vSource, const QString &vDestination); -// Singleton -SINGLETON_DECL(FileHandler) public: - bool init(); - void quit(); + static bool write(const QString &vFileName, const QString &vContent, bool vAppend = true); + static bool read (const QString &vFileName, QString &vContent); -private: - void initConnections(); - - bool write(const QString &vFileName, const QString &vContent, bool vAppend); - bool read (const QString &vFileName, QString &vContent); - -signals: - void didWrite(const QString &vFileName); - void didRead (const QString &vFileName, const QString &vContent); - -public slots: - bool onWrite (const QString &vFileName, const QString &vContent, bool vAppend = true); -private slots: - bool onRead (const QString &vFileName); - - bool onExportLog(); + bool exportLog (); }; } Index: sources/storage/logger.cpp =================================================================== diff -u -rfeb3423b373dc2a2c4267ef9fcb4d924d738423d -r5e78f0799b46963feb5756decb1a27b952cd19b3 --- sources/storage/logger.cpp (.../logger.cpp) (revision feb3423b373dc2a2c4267ef9fcb4d924d738423d) +++ sources/storage/logger.cpp (.../logger.cpp) (revision 5e78f0799b46963feb5756decb1a27b952cd19b3) @@ -27,22 +27,28 @@ using namespace Storage; -// Singleton -SINGLETON_INIT(Logger) - - Logger::Logger(QObject *parent) : QObject(parent) { } bool Logger::init() { + // runs in main thread + Q_ASSERT_X(QThread::currentThread() == qApp->thread() , "_Logger::init", "The Class initialization must be done in Main Thread" ); + + // runs in Logger thread checkLogPath(); qRegisterMetaType("LogType"); initConnections(); return true; } -void Logger::initConnections() { } +void Logger::quit() +{ +} +void Logger::initConnections() +{ +} + void Logger::checkLogPath() { setLogBasePath(); // try to use /media/sd_card on device @@ -56,7 +62,7 @@ { if (vUseApplicationDirPath) { _dir.setPath(qApp->applicationDirPath()); - qDebug() << "WARNING :" << tr("Application Dir Path used for events logging (%1)").arg(_dir.path()); + LOG_EVENT(tr("Application Dir Path used for events logging (%1)").arg(_dir.path())); } else { _dir.setPath(Log_Base_Path_Name); } @@ -76,18 +82,19 @@ _logPathNames[vLogType] = _dir.path() + "/" + _logBasePathNames[vLogType]; if ( ! _dir.exists(_logBasePathNames[vLogType]) ) { if ( ! _dir.mkpath(_logBasePathNames[vLogType]) ) { - qDebug() << "ERROR :" << tr("Can't create %1 log path (%2)") - .arg(_logPrefix[vLogType]) - .arg(_logPathNames[vLogType]) - ; + LOG_ERROR(tr("Can't create %1 log path (%2)") + .arg(_logPrefix[vLogType]) + .arg(_logPathNames[vLogType]) + ); return false; } } return true; } -bool Logger::log(const QString &vContent, LogType vLogType) { - //qDebug() << QThread::currentThread()->objectName(); +void Logger::log(const QString &vContent, Logger::LogType vLogType) +{ + PRINT_THREAD_NAME; QString date = QDate::currentDate().toString(_dateFormat); QString mContent; @@ -105,18 +112,16 @@ mContent += QTime::currentTime().toString(_timeFormat); mContent += _timeSeparator + vContent; QString fileName = date + _dateSeparator + Log_File_Name; - _FileHandler->onWrite(_logPathNames[vLogType] + fileName, mContent + "\r\n"); - qDebug().noquote() << mContent; - - return true; + FileHandler::write(_logPathNames[vLogType] + fileName, mContent + "\r\n", true); + if (vLogType == eLogError) { + qDebug().noquote() << mContent; + } } -void Logger::doLog(const QString &vContent, LogType vLogType) +void Logger::concurrentLog(const QString &vContent, LogType vLogType) { - // // QMetaObject::invokeMethod(this, "log", Qt::AutoConnection, Q_ARG(QString, vContent) , Q_ARG(LogType, vLogType)); - - // /* QFuture future = */QtConcurrent::run(this,&Logger::log, vContent, vLogType); - // // qDebug() << future.result(); - - log(vContent, vLogType); + PRINT_THREAD_NAME; + // QFuture future = + QtConcurrent::run(this,&Logger::log, vContent, vLogType); + // qDebug() << future.result(); } Index: sources/storage/logger.h =================================================================== diff -u -rfeb3423b373dc2a2c4267ef9fcb4d924d738423d -r5e78f0799b46963feb5756decb1a27b952cd19b3 --- sources/storage/logger.h (.../logger.h) (revision feb3423b373dc2a2c4267ef9fcb4d924d738423d) +++ sources/storage/logger.h (.../logger.h) (revision 5e78f0799b46963feb5756decb1a27b952cd19b3) @@ -23,12 +23,22 @@ // Define #define _Logger Storage::Logger::I() -#define LOG_DATUM(vCONTENT) Storage::Logger::I()->doLog(vCONTENT, Storage::Logger::LogType::eLogDatum) -#define LOG_EVENT(vCONTENT) Storage::Logger::I()->doLog(vCONTENT, Storage::Logger::LogType::eLogEvent) -#define LOG_ERROR(vCONTENT) Storage::Logger::I()->doLog(vCONTENT, Storage::Logger::LogType::eLogError) +#define LOG_DATUM(vCONTENT) Storage::Logger::I().concurrentLog(vCONTENT, Storage::Logger::LogType::eLogDatum) +#define LOG_EVENT(vCONTENT) Storage::Logger::I().concurrentLog(vCONTENT, Storage::Logger::LogType::eLogEvent) +#define LOG_ERROR(vCONTENT) Storage::Logger::I().concurrentLog(vCONTENT, Storage::Logger::LogType::eLogError) namespace Storage { +/*! + * \brief The Logger class + * + * \note + * PLEASE BE CAREFUL THIS CLASS IS USING QtConcurrent::run + * IT MEANS ANY OTHER CALL WILL BE DONE IN MAIN THREAD + * AND ONLY PRIVATE VOID LOG (,) IS CALLING IN POOLED THREAD + * PLEASE BE VERY CAREFUL AND DO NOT ADD SIGNAL/SLOTS OR ANY OTHER FUNCTION CALLS. + * ALL THE OTHER CLASSES TO USE THIS CLASS SHOULD ONLY USE LOG_DATUM, LOG_EVENT, LOG_ERROR TO LOG + */ class Logger : public QObject { Q_OBJECT @@ -61,31 +71,31 @@ const char *_dateSeparator = "_" ; const char *_timeSeparator = " , "; - - // Singleton -SINGLETON_DECL(Logger) +//SINGLETON_DECL(Logger) +SINGLETON(Logger) public: bool init(); void quit(); + private: void initConnections(); - void checkLogPath (); - void setLogBasePath(bool vUseApplicationDirPath = false); - bool setLogPath (); - bool setLogPath (LogType vLogType); +private: +// setting up + void checkLogPath (); + void setLogBasePath (bool vUseApplicationDirPath = false); + bool setLogPath (); + bool setLogPath (LogType vLogType); -private slots: - bool log(const QString &vContent, LogType vLogType); +public slots: + void concurrentLog (const QString &vContent, LogType vLogType); -signals: - void didLog(bool ok); +private: + void log (const QString &vContent, LogType vLogType); -public slots: - void doLog(const QString &vContent, LogType vLogType); }; } Index: sources/storage/storageglobals.cpp =================================================================== diff -u -rfeb3423b373dc2a2c4267ef9fcb4d924d738423d -r5e78f0799b46963feb5756decb1a27b952cd19b3 --- sources/storage/storageglobals.cpp (.../storageglobals.cpp) (revision feb3423b373dc2a2c4267ef9fcb4d924d738423d) +++ sources/storage/storageglobals.cpp (.../storageglobals.cpp) (revision 5e78f0799b46963feb5756decb1a27b952cd19b3) @@ -12,7 +12,13 @@ * */ +#include "storageglobals.h" + namespace Storage { + + //QThread _Logger_Thread; + QThread _USBWatcher_Thread; + // USB const char *USB_Mount_Point = "/media/usb/"; const char *USB_File_System = "vfat"; Index: sources/storage/storageglobals.h =================================================================== diff -u -rfeb3423b373dc2a2c4267ef9fcb4d924d738423d -r5e78f0799b46963feb5756decb1a27b952cd19b3 --- sources/storage/storageglobals.h (.../storageglobals.h) (revision feb3423b373dc2a2c4267ef9fcb4d924d738423d) +++ sources/storage/storageglobals.h (.../storageglobals.h) (revision 5e78f0799b46963feb5756decb1a27b952cd19b3) @@ -13,8 +13,14 @@ */ #pragma once +#include + namespace Storage { + // Threading + //extern QThread _Logger_Thread; + extern QThread _USBWatcher_Thread; + // USB extern const char *USB_Mount_Point; extern const char *USB_File_System; Index: sources/storage/usbwatcher.cpp =================================================================== diff -u -rfeb3423b373dc2a2c4267ef9fcb4d924d738423d -r5e78f0799b46963feb5756decb1a27b952cd19b3 --- sources/storage/usbwatcher.cpp (.../usbwatcher.cpp) (revision feb3423b373dc2a2c4267ef9fcb4d924d738423d) +++ sources/storage/usbwatcher.cpp (.../usbwatcher.cpp) (revision 5e78f0799b46963feb5756decb1a27b952cd19b3) @@ -18,6 +18,7 @@ #include // Qt +#include #include // Project @@ -28,23 +29,34 @@ // namespace using namespace Storage; -// Singleton -SINGLETON_INIT(USBWatcher) - -USBWatcher::USBWatcher(QObject *parent) : QObject(parent) -{ +USBWatcher::USBWatcher(QObject *parent) : QObject(parent) { startTimer(_checkInterval); } bool USBWatcher::init() { + // runs in main thread + Q_ASSERT_X(QThread::currentThread() == qApp->thread() , "_USBWatcher::init", "The Class initialization must be done in Main Thread" ); + _USBWatcher_Thread.setObjectName("USB Watcher Thread"); + connect(qApp, &QApplication::aboutToQuit, this, &USBWatcher::quit); + _USBWatcher_Thread.start(); + moveToThread(&_USBWatcher_Thread); + + + // runs in USBWatcher thread initConnections(); + return true; } void USBWatcher::quit() { + // runs in Logger thread + moveToThread(qApp->thread()); + // runs in main thread + _USBWatcher_Thread.quit(); + _USBWatcher_Thread.wait(); } void USBWatcher::initConnections() @@ -63,6 +75,7 @@ } bool USBWatcher::usbSeek(QString &vDevice) { + PRINT_THREAD_NAME; QString device = ""; for (char a = 'a'; a <= 'z'; a++) { device = QString("/dev/sd%1%2").arg(a).arg('1'); @@ -77,11 +90,13 @@ void USBWatcher::timerEvent(QTimerEvent *) { + PRINT_THREAD_NAME; usbcheck(); } void USBWatcher::usbcheck() { + PRINT_THREAD_NAME; QString device = ""; if (usbSeek(device)) { if (! _umounted ) { @@ -122,6 +137,7 @@ bool USBWatcher::usbMount(const QString &vDevice) { + PRINT_THREAD_NAME; bool ok; _usbDrive = vDevice.toLatin1().constData(); ok = mount(_usbDrive, USB_Mount_Point, USB_File_System, 0, "") == 0; @@ -138,6 +154,7 @@ bool USBWatcher::usbUmount(const QString &vDevice) { + PRINT_THREAD_NAME; bool ok; ok = umount(vDevice.toLatin1().constData()) == 0; if (ok) { @@ -146,13 +163,14 @@ emit didUSBDriveUmount(); } else { // the error is irrelevant, commented out for now - usbError(vDevice); + //usbError(vDevice); } return ok; } void USBWatcher::usbRemove() { + PRINT_THREAD_NAME; usbUmount(USB_Mount_Point); _umounted = false; _removed = true; Index: sources/storage/usbwatcher.h =================================================================== diff -u -rfeb3423b373dc2a2c4267ef9fcb4d924d738423d -r5e78f0799b46963feb5756decb1a27b952cd19b3 --- sources/storage/usbwatcher.h (.../usbwatcher.h) (revision feb3423b373dc2a2c4267ef9fcb4d924d738423d) +++ sources/storage/usbwatcher.h (.../usbwatcher.h) (revision 5e78f0799b46963feb5756decb1a27b952cd19b3) @@ -20,7 +20,7 @@ #include "main.h" // Define -#define _USBWatcher USBWatcher::I() +#define _USBWatcher Storage::USBWatcher::I() namespace Storage { @@ -35,14 +35,12 @@ const int _checkInterval = 1000; // in ms // Singleton -SINGLETON_DECL(USBWatcher) +SINGLETON(USBWatcher) public: bool init(); void quit(); - bool isMounted () const; - bool isUmounted() const; protected: void timerEvent(QTimerEvent *) override; @@ -52,6 +50,9 @@ bool usbSeek(QString &vDevice); + bool isMounted () const; + bool isUmounted() const; + signals: void didUSBDriveMount (); void didUSBDriveUmount();