Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

qnetworkaccessmanager QNetworkReply - race condition?

I have this QT-related question. QNetworkAccessManager::get() returns QNetworkReply pointer. I can then connect to its finish slot:

QNetworkReply* r = nam->get(url);
connect(r, SIGNAL(finished()),
            this, SLOT(_finishedThisReply()));

This seems the right way to do things, in particular, with this approach you can have simultaneous requests with the same QNetworkAccessManager object. However, don't we have a race condition here? What if between finishing get and calling connect the finished signal has been sent? Or does QT guarantee that this will not happen? I couldn't find anything about it in QT documentation yet.

like image 564
Andre Avatar asked Sep 05 '25 10:09

Andre


1 Answers

Since you have full control over what happens in the thread you run in, there can be no race conditions since your code is running here.

Of course, it's possible that the network access manager's internals are running in another thread. Suppose the following happened in the QNetworkManager's implementation:

Thread A: QNetworkReply* r = nam->get(url);
Thread B: emit r->finished();
Thread A: connect(r, SIGNAL(finished()), ...);

That would be a problem indeed. Alas, the implementation can do something else:

Thread A: QNetworkReply* r = nam->get(url);
Thread B: QMetaObject::invokeMethod(r, "finished");
          // equivalent to QCoreApplication::postEvent(r, new QMetaCallEvent(...))
Thread A: connect(r, SIGNAL(finished()), ...);
          ...

Here a signal is emitted synchronously, within the reply's thread. This is in contrast to the first variant, where a signal was emitted asynchronously.

Eventually, thread A's control returns to the event loop, and the cross-thread method invocation, in the form of a QMetaCallEvent, is sent to r, emitting the signal.

I'm simplifying, but the semantics of QNetworkReply are those of the second, correct, variant. It "just works". There are no races, even if the network access manager's implementation was running in a separate thread.

like image 61
Kuba hasn't forgotten Monica Avatar answered Sep 09 '25 06:09

Kuba hasn't forgotten Monica