QNetworkAccessManager may cause Symbian device to reboot (Known Issue)
QNetworkAccessManager shares/caches TCP connections and buffers internally, so using it is beneficial in terms of resource usage and latency.
In order to get the best performance when using QNetworkAccessManager, there are a few important things to consider. In principle these guidelines apply on all platforms, but they are of particular importance when developing software with Qt version 4.7.x on Symbian devices.
As a rule of thumb, the fewer instances of the QNetworkAccessManager, the better; the optimum is one instance per process (application). Qt documentation refers to this as 'One QNetworkAccessManager should be enough for the whole Qt application'. By default the details are not shown (see QNetworkAccessManager Class Reference in Qt documentation), therefore this suggestion may sometimes easily go unnoticed.
How to reproduce
There are a few reasons for this:
1) With Qt 4.7.x, QNetworkAccessManager by default manages the underlying bearers, and uses network resources for this (an internal QNetworkSession). Each instance of the class has its own bearer management, causing resource waste. Typical applications do not need more than one bearer controlling entity.
2) Qt 4.7.x bearer management on Symbian is ported on top of per-process API (OpenC). The practical consequence is that several entities controlling the bearer in the same process will interfere with each other. In practice this can be a severe problem, not just a slight performance hit: many QNetworkAccessManagers being created and destroyed may have adverse effects.
3) With Qt 4.6.3. and onwards, this issue may result in the application crashing.
As mentioned, the rule of thumb is to have as few instances of the class as possible.
Sometimes it may be impractical to pass a single instance around. If this really is the case, there are still a few options to mitigate the performance loss and other adverse effects;
1) Let one of the QNetworkAccessManagers handle the bearer management.
Provide the rest of the managers with invalid configuration: QNetworkAccessManager::setConfiguration(). This means that one 'master manager' handles the process-wide bearer management and the others will just use whatever the platform gives (set by the mastering manager). The downside is that if the mastering manager roams, it will break the sockets of the rest of the managers, and the application needs to re-issue requests after the failure.
2) Provide all of the managers with invalid configuration, and create a QNetworkSession to manually control the bearer. This is the way things were done with Qt 4.6.x if non-default bearer management was needed. The downside is that the application needs to handle roaming manually, or to disable it by actively ignoring roaming suggestions.
3) Provide all of the managers with invalid configuration and do nothing more. In practice this means that the platform default configuration will be used in all instances. The downside is that there will be no roaming.
Considering the downsides of the three workarounds, having one QNetworkAccessManager per process is recommended.
- A solution may be available in the Qt 4.8 release.
- Use the Singleton design pattern (see Singleton pattern at qtcentre.org) and allocate QNetworkAccessManager from the heap.