Cache: Use lock guard for locking spinlocks

Now the locks will always be release, also in the presence of an
unantecipated exception.
This commit is contained in:
Johan Wikman
2016-11-29 22:09:27 +02:00
parent efa8713b17
commit 2423031df8
4 changed files with 42 additions and 31 deletions

View File

@ -106,6 +106,31 @@ struct hash<CACHE_KEY>
}
/**
* LockGuard is a RAII class whose constructor acquires a spinlock and
* destructor releases the same spinlock. To be used for locking a spinlock
* in an exceptionsafe manner for the duration of a scope.
*/
class LockGuard
{
public:
LockGuard(SPINLOCK* plock)
: lock_(*plock)
{
spinlock_acquire(&lock_);
}
~LockGuard()
{
spinlock_release(&lock_);
}
private:
LockGuard(const LockGuard&);
LockGuard& operator = (const LockGuard&);
SPINLOCK& lock_;
};
#define CPP_GUARD(statement)\
do { try { statement; } \
catch (const std::exception& x) { MXS_ERROR("Caught standard exception: %s", x.what()); }\

View File

@ -69,18 +69,16 @@ CacheMT* CacheMT::Create(const std::string& name, StorageFactory* pFactory, cons
bool CacheMT::must_refresh(const CACHE_KEY& key, const SessionCache* pSessionCache)
{
spinlock_acquire(&m_lockPending);
bool rv = CacheSimple::do_must_refresh(key, pSessionCache);
spinlock_release(&m_lockPending);
LockGuard guard(&m_lockPending);
return rv;
return do_must_refresh(key, pSessionCache);
}
void CacheMT::refreshed(const CACHE_KEY& key, const SessionCache* pSessionCache)
{
spinlock_acquire(&m_lockPending);
CacheSimple::do_refreshed(key, pSessionCache);
spinlock_release(&m_lockPending);
LockGuard guard(&m_lockPending);
do_refreshed(key, pSessionCache);
}
// static

View File

@ -39,28 +39,22 @@ cache_result_t LRUStorageMT::get_value(const CACHE_KEY& key,
uint32_t flags,
GWBUF** ppvalue)
{
spinlock_acquire(&lock_);
cache_result_t rv = LRUStorage::do_get_value(key, flags, ppvalue);
spinlock_release(&lock_);
LockGuard guard(&lock_);
return rv;
return do_get_value(key, flags, ppvalue);
}
cache_result_t LRUStorageMT::put_value(const CACHE_KEY& key,
const GWBUF* pvalue)
{
spinlock_acquire(&lock_);
cache_result_t rv = LRUStorage::do_put_value(key, pvalue);
spinlock_release(&lock_);
LockGuard guard(&lock_);
return rv;
return do_put_value(key, pvalue);
}
cache_result_t LRUStorageMT::del_value(const CACHE_KEY& key)
{
spinlock_acquire(&lock_);
cache_result_t rv = LRUStorage::do_del_value(key);
spinlock_release(&lock_);
LockGuard guard(&lock_);
return rv;
return do_del_value(key);
}

View File

@ -34,27 +34,21 @@ InMemoryStorageMT* InMemoryStorageMT::create(const std::string& name,
cache_result_t InMemoryStorageMT::get_value(const CACHE_KEY& key, uint32_t flags, GWBUF** ppresult)
{
spinlock_acquire(&lock_);
cache_result_t result = do_get_value(key, flags, ppresult);
spinlock_release(&lock_);
LockGuard guard(&lock_);
return result;
return do_get_value(key, flags, ppresult);
}
cache_result_t InMemoryStorageMT::put_value(const CACHE_KEY& key, const GWBUF* pvalue)
{
spinlock_acquire(&lock_);
cache_result_t result = do_put_value(key, pvalue);
spinlock_release(&lock_);
LockGuard guard(&lock_);
return result;
return do_put_value(key, pvalue);
}
cache_result_t InMemoryStorageMT::del_value(const CACHE_KEY& key)
{
spinlock_acquire(&lock_);
cache_result_t result = do_del_value(key);
spinlock_release(&lock_);
LockGuard guard(&lock_);
return result;
return do_del_value(key);
}