Does QIODevice::waitForReadyRead implicitly flush the output queue (waitForBytesWritten)?

1.6k views Asked by At

If I want to write data to a remote side and wait for its answer, I need at least a waitForReadyRead. But before calling that, do I need to manually flush the output queue using waitForBytesWritten, or does Qt automatically flush the write queue for me? I am operating synchronously (blocking) and therefore in this function I am unable to use the event loop or a local event loop.

When using std::cin, we can be sure that previously written bytes by std::cout will have been flushed. That's the analoguous situation - does it apply to Qt sockets aswell?

2

There are 2 answers

3
TheDarkKnight On

If you look at the source code, being an abstract base class, QIODevice does very little in waitForReadyRead and it's up to the implementation of inherited classes:

bool QIODevice::waitForReadyRead(int msecs)
{
    Q_UNUSED(msecs);
    return false;
}

does it apply to Qt sockets aswell?

As you've stated that you're operating synchronously, I assume you've chosen this for a reason and are aware that on the main thread, any GUI present will freeze during a call to waitForReadyRead. Usually, asynchronous usage for QIODevice is preferred, with Qt being an event-driven framework.

However, the Qt docs state:

Certain subclasses of QIODevice, such as QTcpSocket and QProcess, are asynchronous.

Therefore, if your QIODevice is a socket such as QTcpSocket, then no, you should not be required to call waitForBytesWritten when calling waitForReadyRead.

In the case of a non-synchronous device, it would be required.

0
Johannes Schaub - litb On

I have subsequently asked Thiago Macieira (QtCore maintainer) about the subject and he replied that for QAbstractSocket, both waitForBytesWritten and waitForReadyRead will write pending bytes that were sitting in the qt buffer waiting to be handed over to the OS.

An application that does only waits for bytes to be written and only afterwards reads incoming bytes can potentially deadlock, if the remote site is blocked because of waiting for the other (local) side to read data. Because the remote side blocks, it cannot read data sent by the local side. So if the local side writes too much so that it blocks aswell, each will wait for the other to read their data and deadlock.

Therefore both the bytesWritten and readyRead wait functions process both the qt read and qt write buffer. The waitForBytesWritten may even emit the readyRead signal, which I didn't expect. So the waitForBytesWritten call essentially was redundant and can be removed.