Commit 25213b7c authored by Hugo Beauzée-Luyssen's avatar Hugo Beauzée-Luyssen
Browse files

Cache: Fix a race condition

This was causing the insertion assert to trigger, due a thread querying
the database while:
- Holding the cache lock
- Acquiring the database lock
- Inserting the fetched entity in cache if it didn't exist

While another thread was inserting an entity while:
- Holding the database lock
- Releasing it after the insertion was done
- Holding the cache lock
- Checking that the entity didn't exist in cache

Since the locking order wasn't consistent, the 1st thread was
interupting the 2nd before it was done with the entire insertion
method, causing an inconsistent state.
parent dc197e8d
......@@ -181,13 +181,14 @@ class Cache
template <typename... Args>
static bool insert( DBConnection dbConnection, std::shared_ptr<IMPL> self, const std::string& req, Args&&... args )
{
Lock lock( Mutex );
unsigned int pKey = sqlite::Tools::insert( dbConnection, req, std::forward<Args>( args )... );
if ( pKey == 0 )
return false;
(self.get())->*TABLEPOLICY::PrimaryKey = pKey;
auto cacheKey = CACHEPOLICY::key( self );
Lock lock( Mutex );
// We expect the cache column to be PRIMARY KEY / UNIQUE, so an insertion with
// a duplicated key should have been rejected by sqlite. This indicates an invalid state
assert( Store.find( cacheKey ) == Store.end() );
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment