Fix potential (although improbable) deadlock

This commit is contained in:
Sebastian Messmer 2016-09-24 10:56:36 +02:00
parent b4a609459b
commit 46a2251e9d
4 changed files with 11 additions and 2 deletions

View File

@ -1,5 +1,8 @@
Version 0.9.6 (unreleased)
---------------
Fixed bugs:
* Fix potential (although very improbable) deadlock
Compatibility:
* Compatible with libcurl version >= 7.50.0, and <= 7.21.6 (tested down to 7.19.0)
* Compatible with Crypto++ 5.6.4

View File

@ -111,6 +111,7 @@ void Cache<Key, Value, MAX_ENTRIES>::_deleteEntry(std::unique_lock<std::mutex> *
// i.e. pop() and push() can be called here, except for pop() on the element in _currentlyFlushingEntries
lock->unlock();
value = boost::none; // Call destructor
lockEntryFromBeingPopped.unlock(); // unlock this one first to keep same locking oder (preventing potential deadlock)
lock->lock();
};

View File

@ -42,6 +42,7 @@ namespace cpputils {
template<class LockName>
inline void LockPool<LockName>::lock(const LockName &lock, std::unique_lock<std::mutex> *lockToFreeWhileWaiting) {
ASSERT(lockToFreeWhileWaiting->owns_lock(), "Given lock must be locked");
std::unique_lock<std::mutex> mutexLock(_mutex); // TODO Is shared_lock enough here?
if (_isLocked(lock)) {
// Order of locking/unlocking is important and should be the same order as everywhere else to prevent deadlocks.

View File

@ -23,10 +23,14 @@ namespace cpputils {
~MutexPoolLock() {
if (_pool != nullptr) {
unlock();
}
}
void unlock() {
_pool->release(_lockName);
_pool = nullptr;
}
}
private:
LockPool<LockName> *_pool;