Qt Forum

    • Login
    • Search
    • Categories
    • Recent
    • Tags
    • Popular
    • Users
    • Groups
    • Search
    • Unsolved

    Qt Academy Launch in California!

    Solved QReadWriteLock: cost of lockForRead, unlock and then maybe lockForWrite?

    General and Desktop
    2
    4
    300
    Loading More Posts
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes
    Reply
    • Reply as topic
    Log in to reply
    This topic has been deleted. Only users with topic management privileges can see it.
    • mbruel
      mbruel last edited by

      Hi,
      I'm just discovering QReadWriteLock.
      Would you do something like this

          _secureResultMap.lockForRead();
          Element *evolElement = _results.value(element, nullptr);
          _secureResultMap.unlock();
          if (evolElement)
          {
              QWriteLocker lockResultMap(&_secureResultMap);
              _results.remove(element);
              return evolElement;
          }
      

      Or would you rather go directly with QWriteLocker?
      (like this:

          QWriteLocker lockResultMap(&_secureResultMap);
          Element *evolElement = _results.value(element, nullptr);
          if (evolElement)
          {
              _results.remove(element);
              return evolElement;
          }
      

      I guess it depends on how often I would find the value in my map... well that is something I don't know yet...

      1 Reply Last reply Reply Quote 0
      • mbruel
        mbruel last edited by

        Another example would be this:

        QSharedPointer<SharedObject> CentralizingWeakCache::getCentralizedValue(const QSharedPointer<SharedObject> &sharedPtr)
        {
            QSharedPointer<SharedObject> centralizedValue;
            QSharedPointer<WeakCacheKey> key(new WeakCacheKey(sharedPtr));
        
            _secureCache.lockForRead();
            QWeakPointer<SharedObject> cachedWeakPtr = _cache.value(key, QWeakPointer<SharedObject>());
            _secureCache.unlock();
            if (!cachedWeakPtr.isNull())
                centralizedValue = cachedWeakPtr.toStrongRef();
        
            if (centralizedValue.isNull())
            {
                centralizedValue = sharedPtr;
                centralizedValue->setCacheKey(this, key);
                QWriteLocker lockCache(&secureCache);
                _cache.insert(key, centralizedValue.toWeakRef());                
            }
        
            return centralizedValue;
        }
        

        In that case I know that I would have more reading than writing. A factor between 5 and 10.

        JonB 1 Reply Last reply Reply Quote 0
        • JonB
          JonB @mbruel last edited by JonB

          @mbruel
          I've not used QReadWriteLock, and I may be putting my neck out here, but...

          In, say, your first example, you take a read lock, release it, and then lock for write, and use the result from the read lock (I guess that's what your title is about). Apart from the fact that is "slow", in general pattern you do not want to follow that approach. The whole point is that the value may be changed, deleted, whatever between you releasing the read lock and taking the new write lock. Unless you/someone else know better, that's a no-no as a pattern. You take your write lock, do you your update, then release, all atomic.

          mbruel 1 Reply Last reply Reply Quote 1
          • mbruel
            mbruel @JonB last edited by mbruel

            @JonB
            I see, you're right, for the remove I should lock for the whole operation.
            I guess in fact it is the same for the insert, another thread could insert the similar value in between and I could have some external object using it already.
            Cheers for this.

            1 Reply Last reply Reply Quote 0
            • First post
              Last post