Uploaded image for project: 'Qt'
  1. Qt
  2. QTBUG-13175

QNetworkDiskCache exception - possible race condition

    XMLWordPrintable

Details

    • Bug
    • Resolution: Cannot Reproduce
    • P2: Important
    • None
    • 4.6.3
    • Network: Cache
    • None
    • Windows XP

    Description

      We have encountered a case where the QNetworkDiskCache removes the URL from the cache, only to then try and insert it again soon afterwards. This tries to generate the qWarning() message "NetworkDiskCache::insert() called on a device we don't know about" << device but device has been deleted and an exception is thrown.

      Going by the code comments, it looks like the cancellation of the insertion is intended, but the qWarning() message it generates causes an error. It doesn't always call insert afterwards, so i'm thinking it may be a race condition?

      I've been able to fix the problem by compiling Qt with QT_NO_WARNING_OUTPUT and QT_NO_DEBUG_OUTPUT, or by commenting out the offending qWarning() line.

      qnetworkdiskcache.cpp:291
      bool QNetworkDiskCache::remove(const QUrl &url)
      {
      #if defined(QNETWORKDISKCACHE_DEBUG)
          qDebug() << "QNetworkDiskCache::remove()" << url;
      #endif
          Q_D(QNetworkDiskCache);
      
          // remove is also used to cancel insertions, not a common operation
          QHashIterator<QIODevice*, QCacheItem*> it(d->inserting);
          while (it.hasNext()) {
              it.next();
              QCacheItem *item = it.value();
              if (item && item->metaData.url() == url) {
                  delete item;    <----- IT GETS IN HERE, DELETING THE QIODevice
                  d->inserting.remove(it.key());
                  return true;
              }
          }
      
          if (d->lastItem.metaData.url() == url)
              d->lastItem.reset();
          return d->removeFile(d->cacheFileName(url));
      }
      
      qnetworkdiskcache.cpp:230
      void QNetworkDiskCache::insert(QIODevice *device)
      {
      #if defined(QNETWORKDISKCACHE_DEBUG)
          qDebug() << "QNetworkDiskCache::insert()" << device;
      #endif
          Q_D(QNetworkDiskCache);
          QHash<QIODevice*, QCacheItem*>::iterator it = d->inserting.find(device);
          if (it == d->inserting.end()) {
              qWarning() << "QNetworkDiskCache::insert() called on a device we don't know about" << device;  <--- IT THEN GETS HERE, TRIES TO PRINT OUT QIODevice which is now deleted, causing an exception.
              return;
          }
      
          d->storeItem(it.value());
          delete it.value();
          d->inserting.erase(it);
      }
      

      Attachments

        No reviews matched the request. Check your Options in the drop-down menu of this sections header.

        Activity

          People

            phartman Peter Hartmann (closed Nokia identity) (Inactive)
            mfigg Matthew Figg
            Votes:
            0 Vote for this issue
            Watchers:
            3 Start watching this issue

            Dates

              Created:
              Updated:
              Resolved:

              Gerrit Reviews

                There are no open Gerrit changes