On Dec 7, 2011, at 7:05 PM, Kelvin Chung wrote:
It would appear that the proper way to implement Cache::query() is as follows:
Output query(const Input& in) { boost::shared_lockboost::shared_mutex readLock(mutex); if (cache.count(in) == 0) { readLock.unlock(); boost::unique_lockboost::shared_mutex writeLock(mutex);
// Check to see if the result was added while waiting for lock if (cache.count(in) != 0) return cache[in];
cache[in] = compute_output(in); return cache[in]; } else { return cache[in]; } }
Is this correct? Or maybe it should be this:
Yes, this is correct. Your code properly checks for the case that someone else got the writelock before this thread did. You have no need for upgrade functionality here. If the check that you do inside the writeLock for another writer was expensive or very inconvenient, then you might consider upgrade functionality. But you are correct that you can give only one thread an upgrade lock at a time, and so does you no good unless you have readers that you *know* will never want upgrade/write access. Howard