QTcpSocket readyRead signal waiting for nothing when writing a file in a separate thread



  • Hi,

    I have an annoying bug with my program. The main program is an HTTP web server. Another thread write sometime big amount of data into a file. My problem is when the thread is writing into the file, if i try to send a request to the web server, i got the newConnection signal but the related socket readyRead signal is sometimes coming very later. This problem is randomly happening, some request are very fast and sometimes it may take 5-10 seconds to get the readyRead signal. I use this server locally, so it cannot be a network speed problem. When the thread a finished to write into the file, everything become normal.

    Originally, I'm using libqxt-web to do this, but i'm able to reproduce the problem only with a QTcpServer into a simple program. Note that before using libqtx i was using a QTcpServer in a threaded context (using function incomingConnection, waitForReadyRead, waitForByteWritten...) which was not using the default event based system (newConnection, readyread...). This was working nice, but now i need to get it work with libqtx-web system. But, since i can reproduce the problem without libqxt, i think it's not a problem with that library.

    If i use a large enough sleep between each write into a file, this seems to solve the problem, but it's not a nice solution.

    So my simple program has the following code:

    main.cpp
    @
    int main(int argc, char *argv[])
    {
    qInstallMsgHandler(log_function);

    // Initialize the QT application
    QCoreApplication a(argc, argv);

    signal(SIGTERM, sig_term);
    signal(SIGINT, sig_term);

    // Port
    quint16 port = 8081;

    qDebug("[Main] Initialization server");
    WebServer *pWebServer = new WebServer(QHostAddress::Any, port);
    a.installEventFilter (pWebServer);

    qDebug("[Main] Starting server");
    pWebServer->start();

    qDebug("[Main] Starting worker");
    WorkerThread* pThread = new WorkerThread();
    pThread->start();

    qDebug("[Main] Starting the main loop");
    a.exec();
    qDebug("[Main] Exit the main loop");

    pThread->abort();
    qDebug("[WorkerThread] Wait worker thread");
    pThread->wait();
    qDebug("[WorkerThread] Destroy worker thread");
    delete pThread;

    qDebug("[WorkerThread] Destroy service");
    delete pWebServer;

    return 0;
    }@

    webserver.cpp
    @

    WebServer::WebServer(const QHostAddress &host, quint16 port)
    {
    m_host = host;
    m_port = port;
    m_count = 0;

    m_pServer = new QTcpServer();
    connect(m_pServer, SIGNAL(newConnection()), this, SLOT(acceptConnection()));
    

    }

    WebServer::~WebServer()
    {

    }

    void WebServer::start()
    {
    m_pServer->listen(m_host, m_port);
    }

    void WebServer::acceptConnection()
    {
    qDebug("[WebServer] ---------------------->");
    qDebug("[WebServer] newConnection received");

    QTcpSocket* pSocket = m_pServer->nextPendingConnection ();
    QObject::connect(pSocket, SIGNAL(readyRead()), this, SLOT(incomingData()));
    QObject::connect(pSocket, SIGNAL(disconnected()), this, SLOT(disconnected()));
    QObject::connect(pSocket, SIGNAL(destroyed()), this, SLOT(destroyed()));
    }

    void WebServer::incomingData()
    {
    qDebug("[WebServer] readyRead received");

    QIODevice* pDevice = qobject_cast<QIODevice*>(sender());
    if (!pDevice) return;

    QString szResponse;
    m_count++;
    QString szContent = "Count is: " + QString::number(m_count);

    szResponse = "HTTP/1.1 200 OK\r\n"
    "Content-Type: text/html; charset=utf-8\r\n"
    "Content-Length: " + QString::number(szContent.length()) + "\r\n"
    "Connection: close\r\n"
    "\r\n" + szContent;

    qDebug("[WebServer] socket content sent: %s", qPrintable(szContent));

    pDevice->write(szResponse.toAscii());
    pDevice->close();
    }

    void WebServer::disconnected()
    {
    qDebug("[WebServer] socket disconnected");
    QIODevice* pDevice = qobject_cast<QIODevice*>(sender());
    if (!pDevice) return;

    pDevice->deleteLater();
    }

    void WebServer::destroyed()
    {
    qDebug("[WebServer] socket destroyed");
    qDebug("[WebServer] <----------------------");
    }
    @

    WorkerThread.cpp
    @

    void WorkerThread::run()
    {
    qDebug("[WorkerThread] Start worker thread");

    char* pBuffer;
    int sizeBuf;

    sizeBuf = 1000000;

    int iCount=4000;

    #ifdef MODE_C
    qDebug("[WorkerThread] Mode C");
    FILE * pFile;
    pFile = fopen ("fileout.dat" , "wb");
    if(pFile){
    while(iCount>0 && !m_bStop){
    //qDebug("[WorkerThread] Remaining: %d", iCount);

    pBuffer = (char*)malloc(sizeBuf * sizeof(char));

    fwrite (pBuffer, 1, sizeBuf, pFile);
    fflush (pFile);

    free(pBuffer);
    pBuffer = NULL;

    iCount--;

    //usleep(100);
    }
    }
    qDebug("[WorkerThread] Closing the file");
    fclose (pFile);
    #endif

    qDebug("[WorkerThread] End worker thread");
    }
    @

    Here the output log:

    @
    [lun. déc. 10 14:03:06 2012] [WebServer] ---------------------->
    ->[lun. déc. 10 14:03:06 2012] [WebServer] newConnection received
    ->[lun. déc. 10 14:03:10 2012] [WebServer] Event received SockAct(50)
    [lun. déc. 10 14:03:10 2012] [WebServer] Socket descriptor 262194
    [lun. déc. 10 14:03:10 2012] [WebServer] readyRead received
    [lun. déc. 10 14:03:10 2012] [WebServer] socket content sent: Count is: 3
    [lun. déc. 10 14:03:10 2012] [WebServer] Event received ChildAdded(68)
    [lun. déc. 10 14:03:10 2012] [WebServer] Event received SockAct(50)
    [lun. déc. 10 14:03:10 2012] [WebServer] Socket descriptor 262194
    [lun. déc. 10 14:03:10 2012] [WebServer] Event received ChildRemoved(71)
    [lun. déc. 10 14:03:10 2012] [WebServer] Event received ChildRemoved(71)
    [lun. déc. 10 14:03:10 2012] [WebServer] Event received ChildRemoved(71)
    [lun. déc. 10 14:03:10 2012] [WebServer] socket disconnected
    [lun. déc. 10 14:03:10 2012] [WebServer] Event received DeferredDelete(52)
    [lun. déc. 10 14:03:10 2012] [WebServer] socket destroyed
    [lun. déc. 10 14:03:10 2012] [WebServer] <----------------------
    @

    I'm working on Linux 3.2.0-3-amd64 on Mint LMDE. Someone can tell me, if i'm doing something wrong or if it's a bug in the Qt library?
    I don't see why Qt is blocking the readyRead signal because the main thread has nothing else to do.

    Thank you for you help!


Log in to reply
 

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