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. QTimer in a Singleton QObject class stops emitting timeOut()
QtWS25 Last Chance

QTimer in a Singleton QObject class stops emitting timeOut()

Scheduled Pinned Locked Moved General and Desktop
3 Posts 3 Posters 2.1k Views
  • 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.
  • T Offline
    T Offline
    TOAOMatis
    wrote on last edited by
    #1

    Hi all,

    I'm having troubles synchronizing network communications from my GUI application. Several QoS routines poll both UDP and TCP network devices on different QHostaddresses.
    To streamline the communication over the network I've created a Signleton class named AcpNetwork which holds a QHash<ulong, AcpTransport *> named fifo.
    @private:
    static AcpNetwork *m_Instance;
    typedef struct
    {
    QHostAddress address;
    int retries;
    TransportState state;
    QWaitCondition *wait;
    AcpPacket *request;
    AcpPacket *reply;
    } AcpTransport;
    QTimer *fifoTimer;
    QHash<ulong, AcpTransport *> fifo;
    private slots:
    void handlePackets();@
    The fifoTimer is started at AcpNetwork initialization and ticks every 100ms. At the timeout() signal, handlePackets() is called.
    @AcpNetwork::AcpNetwork(QObject *parent) : QObject(parent)
    {
    QTimer *timer = new QTimer();
    timer->setInterval(100);
    timer->setSingleShot(false);
    connect(timer, SIGNAL(timeout()), this, SLOT(handlePackets()));
    timer->start();
    }@
    handlePackets iterates of the the QHash and sends the AcpPacket request. After several milliseconds the reply is asynchronous handled and assigned to the QHash AcpPacket reply. And the waiting caller (blocked by the QWaitCondition) is signaled that the reply is available.

    handlePackets() only takes action when there are items in the QHash, so the first seconds of my application, this slot does nothing.
    When the first packet is added to the fifo, the machanism works like a charm. I can see that the packet is written to the socket, Wiresharks detects the packet, sees the reply, my application reads the data from the socket and adds the AcpPacket to the reply pointer. The state is set to received and the calling QObject is woken throught the QWaitCondition.

    After that the whole mechanism comes to a stop with no error or warning thrown. I can see that there are request packages added to the fifo, but the handlePackets() slot is never triggered anymore.

    I've searched the interwebz regarding this issue, but so far none of the answers solve my problem:
    http://www.qtcentre.org/threads/30353-QThread-QWaitCondition-and-freeze
    http://stackoverflow.com/a/13225297
    http://qt-project.org/forums/viewthread/11316
    https://qt-project.org/forums/viewthread/26159

    What can be the issue of this matter?

    Hope to hear from you soon and many thanks in advance!

    TOAOMatis

    1 Reply Last reply
    0
    • M Offline
      M Offline
      mcosta
      wrote on last edited by
      #2

      Hi,

      remember that each Thread has its EventLoop; this means that the handlePackets() slot will be triggered only for the QThread who created it.

      Have a look "here":http://qt-project.org/doc/qt-5/threads-qobject.html to more details

      Once your problem is solved don't forget to:

      • Mark the thread as SOLVED using the Topic Tool menu
      • Vote up the answer(s) that helped you to solve the issue

      You can embed images using (http://imgur.com/) or (http://postimage.org/)

      1 Reply Last reply
      0
      • A Offline
        A Offline
        ambershark
        wrote on last edited by
        #3

        Here is some info from the docs on QTimer that may apply to your situation and be helpful:

        In multithreaded applications, you can use QTimer in any thread that has an event loop. To start an event loop from a non-GUI thread, use QThread::exec(). Qt uses the timer's thread affinity to determine which thread will emit the timeout() signal. Because of this, you must start and stop the timer in its thread; it is not possible to start a timer from another thread.

        I noticed you use a QWaitCondition. It could be that the event from the timer is fired off before the wait condition is blocking again. If that happens then the wait will have no idea the event fired off (and was handled/ignored) already and block forever.

        My L-GPL'd C++ Logger github.com/ambershark-mike/sharklog

        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