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

Juha Ruotsalainen juha.ruotsalainen at fastroi.fi
Mon Sep 6 11:44:27 CEST 2010


Thanks for all replies. A very good point about adding a property to QObject. I need to do just that, but to the reply object, not to the NAM, since the reply object's URL contain data that we need when we process the readyRead signals. That's the logical place to store fetch-related properties since those are also needed when processing readyReads.

> > 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.
> 
> I didn't get this. Can you provide a sample code showing the issue/

OK, I'll try to explain this a bit further:
1. Application starts these five fetches.
2. The slots for readyRead and eventually also finished() are called (both namFin, and repFin).

A SIDENOTE: we have few types of fetches that require different handling in finished and readyread slots;
there's a switch-case that checks the hash's value, a QPair mentioned in my first post, and calls the appropriate handler function based on that.

3. The generic handler code for finished, namFin, removes the reply from the hash and finally calls reply's deleteLater.

Here's an excerpt:
        // Remove the reply from the list.
        bool removeReply=true;
        // Check the type.
        switch( NAM_TYPE( networkReplies.value(reply) ) )
        {
            case NAM_AutoUpdate:
                versionQueryFinished( reply );
                break;
            case NAM_ClientData:
                clientDataReceived( reply );
                break;
            case NAM_WorkList:
                workListReceived( reply );
                break;
            case NAM_Task:
                removeReply=false;
                tasksDoneCheck( reply );
                break;
            case NAM_StyleSheet:
                saveStyleSheet( reply );
                break;
            default:
                // Empty on purpose.
                break;
        }
        if(removeReply)
        {
            networkReplies.remove(reply);
        }
        // Close the reply.
        reply->close();
        // Schedule the reply for deletion.
        reply->deleteLater();

4. The removal shield provided removeReply is the method with which the code now works.

5. The point where the application had the access violation exception was when the user pressed a button on UI that should reset the application state. Resetting the application state requires that the networkReplies hash is looped through and each network reply's abort and deletelater are called. 


CURRENT PLAN...
... is to add the two items that are in the hash's value into network reply as properties. This way I can ditch the hash alltogether, and also I don't need to connect to NAM's signals at all.


HOWEVER!
I'm curious to know why hash items were not deleted from the hash on the code sample above? Before removeReply shield being implemented, that is. I had debug prints there and their output were something like:
"""
fetch #1 net access finished, item removed, 4 remaining
fetch #4 net access finished, item removed, 4 remaining
fetch #3 net access finished, item removed, 4 remaining
fetch #5 net access finished, item removed, 4 remaining
fetch #2 net access finished, item removed, 4 remaining
"""

Slaínte,
--
jussi





More information about the Qt-interest-old mailing list