Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. Watchdog class
Forum Updated to NodeBB v4.3 + New Features

Watchdog class

Scheduled Pinned Locked Moved Unsolved General and Desktop
25 Posts 7 Posters 2.5k Views 2 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • SPlattenS SPlatten

    @KroMignon , likewise I've been using instances of QTimer all over, I posted here because it seems not to be working and since everyone can make mistakes its not always obvious what has been done wrong, which was why I was hoping someone could explain why it doesn't seem to be restarting.

    As mentioned in another post I've thought about a work around.

    KroMignonK Offline
    KroMignonK Offline
    KroMignon
    wrote on last edited by
    #16

    @SPlatten said in Watchdog class:

    As mentioned in another post I've thought about a work around.

    This would be my suggestion (maybe there are some typo):

    class clsWatchdog : public QObject 
    {
        Q_OBJECT
    
    private:
        QTimer* mptmrExpiry;
    
    public:
        explicit clsWatchdog(int interval, QObject* parent = nullptr)
        : QObject(parent)
        , mptmrExpiry(new QTimer(this))
        {
            connect(mptmrExpiry, &QTimer::timeout, this, &clsWatchdog::expired);
            mptmrExpiry->setInterval(interval);
            mptmrExpiry->setSingleShot(true);
            //Note: timer will NOT be started here    
        }
    
        void setExpiry(quint16 uint16Expiry)
        {
            //Note: timer will NOT be (re)started here    
            mptmrExpiry->setInterval(uint16Expiry);
        }
        
    public slots:
        void kick()
        {
            // ensure called in right thread
            if(QThread::currentThread() != thread())
            {
                QTimer::singleShot(0, this, &clsWatchdog::kick);
                return;
            }
            // start or restat the timer
            mptmrExpiry->start();
        }
        void pause()
        {
            // ensure called in right thread
            if(QThread::currentThread() != thread())
            {
                QTimer::singleShot(0, this, &clsWatchdog::pause);
                return;
            }
            if(mptmrExpiry->isActive())
                mptmrExpiry->stop();
        }
    
    signals:
        void expired();
    };
    

    It is an old maxim of mine that when you have excluded the impossible, whatever remains, however improbable, must be the truth. (Sherlock Holmes)

    SPlattenS 1 Reply Last reply
    2
    • KroMignonK KroMignon

      @SPlatten said in Watchdog class:

      As mentioned in another post I've thought about a work around.

      This would be my suggestion (maybe there are some typo):

      class clsWatchdog : public QObject 
      {
          Q_OBJECT
      
      private:
          QTimer* mptmrExpiry;
      
      public:
          explicit clsWatchdog(int interval, QObject* parent = nullptr)
          : QObject(parent)
          , mptmrExpiry(new QTimer(this))
          {
              connect(mptmrExpiry, &QTimer::timeout, this, &clsWatchdog::expired);
              mptmrExpiry->setInterval(interval);
              mptmrExpiry->setSingleShot(true);
              //Note: timer will NOT be started here    
          }
      
          void setExpiry(quint16 uint16Expiry)
          {
              //Note: timer will NOT be (re)started here    
              mptmrExpiry->setInterval(uint16Expiry);
          }
          
      public slots:
          void kick()
          {
              // ensure called in right thread
              if(QThread::currentThread() != thread())
              {
                  QTimer::singleShot(0, this, &clsWatchdog::kick);
                  return;
              }
              // start or restat the timer
              mptmrExpiry->start();
          }
          void pause()
          {
              // ensure called in right thread
              if(QThread::currentThread() != thread())
              {
                  QTimer::singleShot(0, this, &clsWatchdog::pause);
                  return;
              }
              if(mptmrExpiry->isActive())
                  mptmrExpiry->stop();
          }
      
      signals:
          void expired();
      };
      
      SPlattenS Offline
      SPlattenS Offline
      SPlatten
      wrote on last edited by SPlatten
      #17

      @KroMignon Very soon I will post the new version of the class, which is simpler.

      In developing this now, I am getting lots of what I believe are wrong clazy warings, e.g.:

          mtmrExpiry.setInterval(std::chrono::milliseconds(clsWatchdog::mscint16Timer));
          mtmrExpiry.setSingleShot(false);
          QObject::connect(&mtmrExpiry, &QTimer::timeout, this, &clsWatchdog::onTimeout);
          mtmrExpiry.start();
      

      There is a clazy warning on the connect line:

      QTimer::timeout is not a signal [clazy-connect-non-signal]
      

      What could be causing this? QTimer is defined as a member of the class, as is the slot onTimeout:

          class clsWatchdog : public QObject {
          Q_OBJECT
      
          private:
              static const int mscint16Default;
              static const int mscint16Timer;
      
              QTimer mtmrExpiry;
         ...
          private slots:
              void onTimeout();
          };
      

      Another clazy message:

      Emit keyword being used with non-signal clsWatchdog::expired [clazy-incorrect-emit]
      

      This is on:

      emit expired();
      

      Which is called in one of my class methods, there is the prototype in the class:

          signals:
              void expired();
      

      Kind Regards,
      Sy

      1 Reply Last reply
      0
      • SPlattenS Offline
        SPlattenS Offline
        SPlatten
        wrote on last edited by SPlatten
        #18

        Here is the finished clsWatchdog which despite the clazy messages works, prototype:

        #ifndef CLSWATCHDOG_H
                #define CLSWATCHDOG_H
            
                #include <QTimer>
            
                class clsWatchdog : public QObject {
                Q_OBJECT
            
                private:
                    static const int mscint16Default;
                    static const int mscint16Timer;
            
                    QTimer mtmrExpiry;
                    quint16 muint16Counter, muint16Setpoint;
            
                public:
                    explicit clsWatchdog();
                    ~clsWatchdog();
            
                    void kick();
                    void pause();
                    void resume();
            
                signals:
                    void expired();
            
                private slots:
                    void onTimeout();
                };
            #endif // CLSWATCHDOG_H
        

        Implementation:

        /**
         * File:    clsWatchdog.cpp
         * Notes:   Contains implementation of the watchdog class
         * History: 2021/01/14 Created by Simon Platten
         */
        #include "../clsDebugService.h"
        #include "clsWatchdog.h"
        //Static initialisation
        const int clsWatchdog::mscint16Default = 12;    //Counter setpoint
        const int clsWatchdog::mscint16Timer = 1000;    //Milliseconds
        /**
         * @brief clsWatchdog::clsWatchdog - Class constructor
         */
        clsWatchdog::clsWatchdog() : muint16Counter(0)
                                   , muint16Setpoint(clsWatchdog::mscint16Default) {
            mtmrExpiry.setInterval(std::chrono::milliseconds(clsWatchdog::mscint16Timer));
            mtmrExpiry.setSingleShot(false);
            QObject::connect(&mtmrExpiry, &QTimer::timeout, this, &clsWatchdog::onTimeout);
            mtmrExpiry.start();
        }
        /**
         * @brief clsWatchdog::~clsWatchdog - Class destructor
         */
        clsWatchdog::~clsWatchdog() {
            if ( mtmrExpiry.isActive() == true ) {
                mtmrExpiry.stop();
            }
            QObject::disconnect(&mtmrExpiry, &QTimer::timeout, this, &clsWatchdog::onTimeout);
        }
        /**
         * @brief clsWatchdog::kick - Keep watchdog from expiring
         */
        void clsWatchdog::kick() {
            //Reset counter
            muint16Counter = 0;
        }
        /**
         * @brief clsWatchdog::onTimeout
         */
        void clsWatchdog::onTimeout() {
            //Increment the counter
            if ( ++muint16Counter >= muint16Setpoint ) {
                emit expired();
            }
        }
        /**
         * @brief clsWatchdog::pause - Use resume to restart
         */
        void clsWatchdog::pause() {
            mtmrExpiry.stop();
        }
        /**
         * @brief clsWatchdog::resume
         */
        void clsWatchdog::resume() {
            mtmrExpiry.start();
        }
        

        Kind Regards,
        Sy

        1 Reply Last reply
        0
        • SPlattenS Offline
          SPlattenS Offline
          SPlatten
          wrote on last edited by
          #19

          So going back to my original purpose...having written and tested this class which works perfectly when running the application it resides in as a standalone module.

          Now I'm launching this application from another Qt process, the process of launching this is:

              QProcess::setProgram(crstrProgram);
              //Register the module
              clsModule::registerModule(this, crstrAlias);
          
              if ( blnStart != true ) {
                  return;
              }
              //Start the process
              start();
              //Monitor when this process changes state
              connect(this, &QProcess::stateChanged, this
                          , [this](QProcess::ProcessState newState) {
                  const qint64 cint64PID = processId();
          
                  if ( newState == QProcess::NotRunning ) {
              //Only create the new instance if 'this' module already has a known PID
              //and the PID valid and different from existing knownPID
                      if ( mint64PID != 0 && cint64PID > 0 && cint64PID != mint64PID ) {
              //Remove this instance of the module
                          clsModule::newInstanceOf(*this);
                      }
                  } else if ( newState == QProcess::Running && cint64PID > 0 ) {
                      const QString& crstrProgram(program());
                      emit PID(crstrProgram, cint64PID);
                  }
              });
          

          crstrProgram is a passed in parameter defined as const QString&, it contains the name of the module / process to launch in this case mdFileIO.

          I can see by looking at the running processes that both the launcher and mdFileIO are running, however when mdFileIO is started this way, the watchdog does not work and when I attach to the process the timer isn't running. Can anyone suggest why?

          Kind Regards,
          Sy

          KroMignonK 1 Reply Last reply
          0
          • SPlattenS SPlatten

            So going back to my original purpose...having written and tested this class which works perfectly when running the application it resides in as a standalone module.

            Now I'm launching this application from another Qt process, the process of launching this is:

                QProcess::setProgram(crstrProgram);
                //Register the module
                clsModule::registerModule(this, crstrAlias);
            
                if ( blnStart != true ) {
                    return;
                }
                //Start the process
                start();
                //Monitor when this process changes state
                connect(this, &QProcess::stateChanged, this
                            , [this](QProcess::ProcessState newState) {
                    const qint64 cint64PID = processId();
            
                    if ( newState == QProcess::NotRunning ) {
                //Only create the new instance if 'this' module already has a known PID
                //and the PID valid and different from existing knownPID
                        if ( mint64PID != 0 && cint64PID > 0 && cint64PID != mint64PID ) {
                //Remove this instance of the module
                            clsModule::newInstanceOf(*this);
                        }
                    } else if ( newState == QProcess::Running && cint64PID > 0 ) {
                        const QString& crstrProgram(program());
                        emit PID(crstrProgram, cint64PID);
                    }
                });
            

            crstrProgram is a passed in parameter defined as const QString&, it contains the name of the module / process to launch in this case mdFileIO.

            I can see by looking at the running processes that both the launcher and mdFileIO are running, however when mdFileIO is started this way, the watchdog does not work and when I attach to the process the timer isn't running. Can anyone suggest why?

            KroMignonK Offline
            KroMignonK Offline
            KroMignon
            wrote on last edited by KroMignon
            #20

            @SPlatten said in Watchdog class:

            Can anyone suggest why?

            As I have written before: I suppose you try to start the timer from the wrong thread. QTimer start()/stop() must be called within the thread in which the timer is running.

            It is an old maxim of mine that when you have excluded the impossible, whatever remains, however improbable, must be the truth. (Sherlock Holmes)

            SPlattenS 1 Reply Last reply
            1
            • KroMignonK KroMignon

              @SPlatten said in Watchdog class:

              Can anyone suggest why?

              As I have written before: I suppose you try to start the timer from the wrong thread. QTimer start()/stop() must be called within the thread in which the timer is running.

              SPlattenS Offline
              SPlattenS Offline
              SPlatten
              wrote on last edited by SPlatten
              #21

              @KroMignon, The instance of clsWatchdog is in the application class:

                  class clsModHelper : public QObject {
                  Q_OBJECT
              
                  protected:
                      bool mblnStandalone;
                      double mdblVersion;
                      FILE* mfpDbgLog;
                      qint64 mint64AppPID;
                      clsWatchdog mobjWatchdog;
              ...
              

              This class is the base class for the application:

                  class clsModFileIO : public clsModHelper {
              

              The only instance of this class is created in:

              int main(int intArgc, char* parystrArgv[]) {
                  QCoreApplication a(intArgc, parystrArgv);
                  clsModFileIO obj(intArgc, parystrArgv);
                  return a.exec();
              }
              

              The watchdog timer is started in its own default constructor which as its declared as a member of clsModHelper, must be in the main thread ?

              Again, what I'm struggling to understand is why it works perfectly when the process is launched directly, but not from the other process using QProcess ?

              Kind Regards,
              Sy

              KroMignonK 1 Reply Last reply
              0
              • SPlattenS SPlatten

                @KroMignon, The instance of clsWatchdog is in the application class:

                    class clsModHelper : public QObject {
                    Q_OBJECT
                
                    protected:
                        bool mblnStandalone;
                        double mdblVersion;
                        FILE* mfpDbgLog;
                        qint64 mint64AppPID;
                        clsWatchdog mobjWatchdog;
                ...
                

                This class is the base class for the application:

                    class clsModFileIO : public clsModHelper {
                

                The only instance of this class is created in:

                int main(int intArgc, char* parystrArgv[]) {
                    QCoreApplication a(intArgc, parystrArgv);
                    clsModFileIO obj(intArgc, parystrArgv);
                    return a.exec();
                }
                

                The watchdog timer is started in its own default constructor which as its declared as a member of clsModHelper, must be in the main thread ?

                Again, what I'm struggling to understand is why it works perfectly when the process is launched directly, but not from the other process using QProcess ?

                KroMignonK Offline
                KroMignonK Offline
                KroMignon
                wrote on last edited by
                #22

                @SPlatten It is very complicated to follow you.

                I don't really understand what is the purpose of your code, and which clsWatchdog instance you are talking about.

                What I believe to have understand:
                You have create software which starts other application with help of a custome QProcess class, why not.

                What I do not understand:

                • what is the purpose of the clsWatchdog ?
                • is clsWatchdog used by "launcher" application? Is this one which is not working as expected?
                • is clsWatchdog used by "external" application? Is this one which is not working as expected?

                It is an old maxim of mine that when you have excluded the impossible, whatever remains, however improbable, must be the truth. (Sherlock Holmes)

                SPlattenS 1 Reply Last reply
                0
                • KroMignonK KroMignon

                  @SPlatten It is very complicated to follow you.

                  I don't really understand what is the purpose of your code, and which clsWatchdog instance you are talking about.

                  What I believe to have understand:
                  You have create software which starts other application with help of a custome QProcess class, why not.

                  What I do not understand:

                  • what is the purpose of the clsWatchdog ?
                  • is clsWatchdog used by "launcher" application? Is this one which is not working as expected?
                  • is clsWatchdog used by "external" application? Is this one which is not working as expected?
                  SPlattenS Offline
                  SPlattenS Offline
                  SPlatten
                  wrote on last edited by
                  #23

                  @KroMignon , the launcher is the main engine, the processes it launchers are helper modules. The launcher will communicate with helpers to request services which the helpers will provide. Each helper will use the watchdog, it’s kept alive by the regular communication from the engine. If the engine is terminated then the communication stops and the purpose of the helpers ends so the watchdog will expire and each helper will terminate.

                  Hope that helps?

                  Kind Regards,
                  Sy

                  1 Reply Last reply
                  0
                  • Christian EhrlicherC Online
                    Christian EhrlicherC Online
                    Christian Ehrlicher
                    Lifetime Qt Champion
                    wrote on last edited by Christian Ehrlicher
                    #24

                    @SPlatten said in Watchdog class:

                    If the engine is terminated then the communication stops and the purpose of the helpers ends so the watchdog will expire and each helper will terminate.

                    Use a QTimer instead some strange self-written classes.

                    Qt Online Installer direct download: https://download.qt.io/official_releases/online_installers/
                    Visit the Qt Academy at https://academy.qt.io/catalog

                    1 Reply Last reply
                    0
                    • SPlattenS SPlatten

                      @KroMignon , reading something is not proof that it does what it says! The reason I posted here in the first place is because having read the documentation, it doesn't seem to do what it is documented.

                      I wish you would stop playing the same old record, its very tiresome and boring, just because once I said someplace that I didn't read the documentation does not make it my life story so get over it and move on.

                      For the record I have been developing and writing software since 1987 professionally, so to say I don't read is insulting and wrong.

                      W Offline
                      W Offline
                      wrosecrans
                      wrote on last edited by
                      #25

                      @SPlatten said in Watchdog class:

                      @KroMignon , reading something is not proof that it does what it says! The reason I posted here in the first place is because having read the documentation, it doesn't seem to do what it is documented.

                      You seem really dedicated to having an XY problem for some reason: https://xyproblem.info/

                      Why not just post about your original confusion with the documentation of QTimer? You say "it doesn't seem to do what it is documented" but you haven't actually explained what problem you were having with it. If there is a bug (in either the docs or the implementation), sharing the specifics will help get it fixed. If there isn't a bug in QTimer, sharing the specifics will help you get past the bug in your code using it.

                      1 Reply Last reply
                      0

                      • Login

                      • Login or register to search.
                      • First post
                        Last post
                      0
                      • Categories
                      • Recent
                      • Tags
                      • Popular
                      • Users
                      • Groups
                      • Search
                      • Get Qt Extensions
                      • Unsolved