Restored thread checks on database accesses
This commit is contained in:
@@ -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;
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
Reference in New Issue
Block a user