Confused by Qt Object Model and QTimer



  • I'm using a QTimer as a sentinel against drop-out of data from a remote host that isn't the result of a dropped connection. The initialize() slot is tied to the started() signal from the thread in which it resides:

    void TapDisplayCommunicationHandler::initialize()
    {
      heartbeat_timer = new QTimer(this);
      QObject::connect(heartbeat_timer, SIGNAL(timeout()), 
                         this, SLOT(handleHeartbeatTimeout()));
    }
    

    Since this timer is meant to indicate when data flow stops, I don't start it until the actual connection is established:

    void TapDisplayCommunicationHandler::
    signalConnectionEstablished()
    {
      emit connectionEstablished();
      
      // start "heartbeat" timer to wait for data to arrive
      heartbeat_timer->start(10000);
    }
    

    When data arrives, I restart the timer to start the clock over:

    void TapDisplayCommunicationHandler::
      processIncomingData(QDataStream& input_stream)
    {
      // we've received new data before the heartbeat timer timeout.  Reset thetimer
      heartbeat_timer->start();
    
    

    If the timeout() signal hits, I emit an error to my main thread:

    void TapDisplayCommunicationHandler::handleHeartbeatTimeout()
    {
      // don't allow any more timer events
      heartbeat_timer->stop();
    
      // we've stopped receiving data.  Emit an error signal
      emit connectionLost(connection_name);
    }
    

    This implementation presents two problems:

    • I have to call stop() on the timer on every flavor of connection loss to prevent any more heartbeat signals

    • When/how do I delete this timer? If I call 'delete' from my destructor, the documentation says I could crash my app if there are pending events. If I want to use 'deleteLater()' what signal am I tying it to? Also, how do I delete the last instance of this timer after the event loop stops running? It seems to me the last instance will always leak if I rely on deleteLater(), since it will not execute if the event loop is stopped


  • Qt Champions 2016

    Hi,
    @DRoscoe said in Confused by Qt Object Model and QTimer:

    When/how do I delete this timer?

    Well, when is up to you, as to how - use QObject::deleteLater. ;)

    If I want to use 'deleteLater()' what signal am I tying it to?

    I don't follow. You can call slots as functions, because in the end they're just functions.

    It seems to me the last instance will always leak if I rely on deleteLater(), since it will not execute if the event loop is stopped.

    All pending delete events are processed before the event loop exits, if that's what you're asking so there's no leak (and you gave it a parent anyway, so no need to worry about the last timer).

    As a side note, why don't you put the timer as an auto-storage (stack) variable in your class and just call QTimer::start, QTimer::stop where appropriate. I don't see any gain in allocating it on the heap in this case.

    Kind regards.


  • Moderators

    @DRoscoe said in Confused by Qt Object Model and QTimer:

    void TapDisplayCommunicationHandler::initialize()
    {
      heartbeat_timer = new QTimer(this);
      ...
    }
    

    In the snippet above, you have set your TapDisplayCommunicationHandler as the parent of the QTimer. Therefore, when you delete your TapDisplayCommunicationHandler, the QTimer will automatically get deleted too. You don't need to do anything else.



  • @DRoscoe said in Confused by Qt Object Model and QTimer:

    I have to call stop() on the timer on every flavor of connection loss to prevent any more heartbeat signals

    Looking at your code you probably want to call heartbeat_timer->setSingleShot(true); so it stops automatically after a timeout.

    @DRoscoe said in Confused by Qt Object Model and QTimer:

    When/how do I delete this timer?

    As mentioned already, since you pass a parent in the constructor, Qt will take care of deleting it



  • @VRonin I considered that, but it doesn't gain me much.



  • @kshegunov Thanks. I took your advice and made it a class attribute.


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.