Restored thread checks on database accesses

This commit is contained in:
emeric
2022-01-20 19:56:45 +01:00
parent 9e64287383
commit d52cc71667
4 changed files with 40 additions and 21 deletions
+2 -10
View File
@@ -456,14 +456,6 @@ Session::Session(Db& db)
_session.mapClass<User>("user"); _session.mapClass<User>("user");
} }
enum class OwnedLock
{
None,
Shared,
Unique,
};
UniqueTransaction::UniqueTransaction(RecursiveSharedMutex& mutex, Wt::Dbo::Session& session) UniqueTransaction::UniqueTransaction(RecursiveSharedMutex& mutex, Wt::Dbo::Session& session)
: _lock {mutex}, : _lock {mutex},
_transaction {session} _transaction {session}
@@ -479,13 +471,13 @@ SharedTransaction::SharedTransaction(RecursiveSharedMutex& mutex, Wt::Dbo::Sessi
void void
Session::checkUniqueLocked() Session::checkUniqueLocked()
{ {
// assert(lockDebug[&_db.getMutex()] == OwnedLock::Unique); assert(_db.getMutex().isUniqueLocked());
} }
void void
Session::checkSharedLocked() Session::checkSharedLocked()
{ {
// assert(lockDebug[&_db.getMutex()] != OwnedLock::None); assert(_db.getMutex().isSharedLocked());
} }
UniqueTransaction UniqueTransaction
@@ -74,8 +74,6 @@ namespace Database
Wt::Dbo::Session& getDboSession() { return _session; } Wt::Dbo::Session& getDboSession() { return _session; }
private: private:
Session(std::shared_mutex& mutex, Wt::Dbo::SqlConnectionPool& connectionPool);
void doDatabaseMigrationIfNeeded(); void doDatabaseMigrationIfNeeded();
Db& _db; Db& _db;
+34 -9
View File
@@ -24,7 +24,9 @@
void void
RecursiveSharedMutex::lock() RecursiveSharedMutex::lock()
{ {
if (_uniqueOwner == std::this_thread::get_id()) const auto thisThreadId {std::this_thread::get_id()};
if (_uniqueOwner == thisThreadId)
{ {
// already locked // already locked
_uniqueCount++; _uniqueCount++;
@@ -32,7 +34,7 @@ RecursiveSharedMutex::lock()
else else
{ {
_mutex.lock(); _mutex.lock();
_uniqueOwner = std::this_thread::get_id(); _uniqueOwner = thisThreadId;
assert(_uniqueCount == 0); assert(_uniqueCount == 0);
_uniqueCount = 1; _uniqueCount = 1;
} }
@@ -53,10 +55,12 @@ RecursiveSharedMutex::unlock()
void void
RecursiveSharedMutex::lock_shared() RecursiveSharedMutex::lock_shared()
{ {
if (_uniqueOwner == std::this_thread::get_id()) const auto thisThreadId {std::this_thread::get_id()};
if (_uniqueOwner == thisThreadId )
{ {
// alone here, no need to lock // alone here, no need to lock
_sharedCounts[std::this_thread::get_id()]++; _sharedCounts[thisThreadId]++;
return; return;
} }
@@ -66,7 +70,7 @@ RecursiveSharedMutex::lock_shared()
{ {
std::scoped_lock lock {_sharedCountMutex}; std::scoped_lock lock {_sharedCountMutex};
auto& sharedCount {_sharedCounts[std::this_thread::get_id()]}; auto& sharedCount {_sharedCounts[thisThreadId]};
if (sharedCount == 0) if (sharedCount == 0)
needLock = true; needLock = true;
else else
@@ -80,17 +84,19 @@ RecursiveSharedMutex::lock_shared()
assert(_uniqueOwner == std::thread::id {}); assert(_uniqueOwner == std::thread::id {});
std::scoped_lock lock {_sharedCountMutex}; std::scoped_lock lock {_sharedCountMutex};
_sharedCounts[std::this_thread::get_id()]++; _sharedCounts[thisThreadId]++;
} }
} }
void void
RecursiveSharedMutex::unlock_shared() RecursiveSharedMutex::unlock_shared()
{ {
if (_uniqueOwner == std::this_thread::get_id()) const auto thisThreadId {std::this_thread::get_id()};
if (_uniqueOwner == thisThreadId )
{ {
// alone here, no need to lock // alone here, no need to lock
auto& sharedCount {_sharedCounts[std::this_thread::get_id()]}; auto& sharedCount {_sharedCounts[thisThreadId ]};
assert(sharedCount > 0); assert(sharedCount > 0);
--sharedCount; --sharedCount;
@@ -102,7 +108,7 @@ RecursiveSharedMutex::unlock_shared()
{ {
std::scoped_lock lock {_sharedCountMutex}; std::scoped_lock lock {_sharedCountMutex};
auto& sharedCount {_sharedCounts[std::this_thread::get_id()]}; auto& sharedCount {_sharedCounts[thisThreadId]};
assert(sharedCount > 0); assert(sharedCount > 0);
needUnlock = (--sharedCount == 0); needUnlock = (--sharedCount == 0);
} }
@@ -110,3 +116,22 @@ RecursiveSharedMutex::unlock_shared()
if (needUnlock) if (needUnlock)
_mutex.unlock_shared(); _mutex.unlock_shared();
} }
#ifndef NDEBUG
bool
RecursiveSharedMutex::isUniqueLocked()
{
return _uniqueOwner == std::this_thread::get_id();
}
bool
RecursiveSharedMutex::isSharedLocked()
{
const auto thisThreadId {std::this_thread::get_id()};
if (_uniqueOwner == thisThreadId )
return true;
std::scoped_lock lock {_sharedCountMutex};
return _sharedCounts[thisThreadId] > 0;
}
#endif
@@ -34,6 +34,10 @@ class RecursiveSharedMutex
void lock_shared(); void lock_shared();
void unlock_shared(); void unlock_shared();
#ifndef NDEBUG
bool isSharedLocked();
bool isUniqueLocked();
#endif // NDEBUG
private: private:
std::shared_mutex _mutex; std::shared_mutex _mutex;
std::thread::id _uniqueOwner; std::thread::id _uniqueOwner;