1

I have a strange behavior with Lambda and timer on Qt 5.7.1. Probably a mistake from me.

I start a connection with a socket and set a timer to check whether it was connected or not after a certain amount of time.

The signal connected of the socket will stop the time.

However, with the following implementation, the timer does not stop even if the connected signal is called.

constructor:

m_connectTimeout.setInterval(5000);

connect(&m_socket, &QLocalSocket::connected, [&]()
{
    // this is called first and should stop the timer.
    m_connectTimeout.stop();
});


connect(&m_connectTimeout, &QTimer::timeout, [&](){
       // this is still called
});

Here is a minimum example with problem reproducible on Qt5.7.1 and Windows 10.

#include <QtCore>
#include <QtNetwork>

#define PIPENAME "testbug"

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);

    QTimer timer;
    QLocalSocket socketClient, *socketServer;
    QLocalServer server;
    timer.setInterval(2000);


    QObject::connect(&timer, &QTimer::timeout, [&]
    {
        qDebug() << "client connection timed out";
        timer.stop();
    });

    QObject::connect(&socketClient, &QLocalSocket::connected, [&]
    {
        qDebug() << "client connected";
        timer.stop();
    });

    QObject::connect(&server, &QLocalServer::newConnection, [&]
    {
        qDebug() << "server got connection";
        socketServer = server.nextPendingConnection();
    });

    server.setSocketOptions(QLocalServer::WorldAccessOption);
    server.listen(PIPENAME);

    qDebug() << "client connecting. . .";
    socketClient.connectToServer(PIPENAME, QLocalSocket::ReadWrite);
    timer.start();

    return a.exec();
}

Output of the program:

client connecting. . .
client connected
server got connection
client connection timed out

I also noticed it's not always reproducible and seems somehow random.

Damien
  • 1,492
  • 10
  • 32
  • Does ```m_connectTimeout.stop()``` actually run? Set a breakpoint and see if it runs – Victor Tran Jan 17 '17 at 11:24
  • 1
    Please try providing an [MCVE](https://stackoverflow.com/help/mcve). I can't think of any reason why `m_connectTimeout.stop()` doesn't stop the timer (are you really sure it is called first?). Here is a [minimal example](https://gist.github.com/micjabbour/292d14219a20ef00f8d4d1e332916b5c) that works and doesn't reproduce the issue. – Mike Jan 17 '17 at 13:45
  • @Victor, yes it does run, I actually have debug output there. – Damien Jan 18 '17 at 01:31
  • @Mike done and edited – Damien Jan 18 '17 at 01:56
  • @Mike sorry just now, didn't thought you'd be so fast – Damien Jan 18 '17 at 02:06
  • @Damien, never mind, I am looking into that :) – Mike Jan 18 '17 at 02:13

1 Answers1

1

Actually it seems the code works, it's just that the connection is so fast, that the timer.stop is called before the timer.start.

Starting the timer before calling connect to server seems to solve the issue

m_timer.start();
m_socketClient.connectToServer(PIPENAME, QLocalSocket::ReadWrite);

This would mean that connectToServer does some calls on the event loop in the background, allowing the slots to be called, even before the next line is executed.

Damien
  • 1,492
  • 10
  • 32
  • yes, that is the problem, I was writing an answer. The `connected()` signal is emitted from within `connectToServer()` and the timer is started after it has been stopped in your slot. – Mike Jan 18 '17 at 02:25