[Qt-interest] QNetworkAccessManager and a QHash of QNetworkReply pointers

Juha Ruotsalainen juha.ruotsalainen at fastroi.fi
Mon Sep 6 09:33:37 CEST 2010


Hi there,

My Friday was spent tracking down this mysterious bug. At least mysterious to me...

Our application uses a QNetworkAccessManager (NAM) to perform all net access. The QNetworkReply pointers that NAM's get routine returns are stored into a QHash where reply pointers are keys into the hash and values consist of a QPair<bool, some_enum_type>.

NAM's and reply's finished signals and reply's readyRead are connected to respective handler slots in the application, let's call them namFin, repFin, repRead. namFin's task is to collectively remove items from the hash once once network fetches complete and call reply's deleteLater().

What I noticed on Friday was that:
1. namFin was called before repFin. IMHO, I think that it's illogical, I would imagine that the NAM would emit finished() once reply has finished(), being a _manager_ after all.

2. When our application starts up, there are two network fetches that work as planned, and they are not handled in parallel: first we make a software update check, once that finishes we check if some client-specific settings have changed on our server. Here the logic works as planned: namRep removes autoupdater's reply from the hash, client data checker is added to the hash and promptly removed once that fetch completes.

3. But, the phase of app startup fails: we start to download data from five servers and NAM operates those fetches in parallel. namFin tries to remove keys&values from the hash using hash's remove function, but nothing was actually removed from the hash. This caused an access violation exception when using the application since our app was of the opinion that there is a fetch going on (there are entries in the hash), but the underlaying system (OS/Qt framework) had already freed the memory related to that pointer.

4. When I relocated the hash remove function call to repFin instead of namFin the hash entry logic started to work.

Is my problem in the order of finished() signals? Is the combination of calling deleteLater for a reply before the reply itself has finished poisonous? What kind of magic is going on in the background?

Slaínte,
--
jussi





More information about the Qt-interest-old mailing list