Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. QReadWriteLock: cost of lockForRead, unlock and then maybe lockForWrite?
QtWS25 Last Chance

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

Scheduled Pinned Locked Moved Solved General and Desktop
4 Posts 2 Posters 521 Views
  • 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.
  • mbruelM Offline
    mbruelM Offline
    mbruel
    wrote on last edited by
    #1

    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
    0
    • mbruelM Offline
      mbruelM Offline
      mbruel
      wrote on last edited by
      #2

      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.

      JonBJ 1 Reply Last reply
      0
      • mbruelM mbruel

        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.

        JonBJ Online
        JonBJ Online
        JonB
        wrote on last edited by JonB
        #3

        @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.

        mbruelM 1 Reply Last reply
        1
        • JonBJ 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.

          mbruelM Offline
          mbruelM Offline
          mbruel
          wrote on last edited by mbruel
          #4

          @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
          0

          • Login

          • Login or register to search.
          • First post
            Last post
          0
          • Categories
          • Recent
          • Tags
          • Popular
          • Users
          • Groups
          • Search
          • Get Qt Extensions
          • Unsolved