mirror of
https://gitlab.isc.org/isc-projects/kea
synced 2025-08-30 13:37:55 +00:00
[#2448] add MultiThreadingLock
This commit is contained in:
@@ -227,6 +227,12 @@ MultiThreadingCriticalSection::~MultiThreadingCriticalSection() {
|
|||||||
MultiThreadingMgr::instance().exitCriticalSection();
|
MultiThreadingMgr::instance().exitCriticalSection();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
MultiThreadingLock::MultiThreadingLock(std::mutex& mutex) {
|
||||||
|
if (MultiThreadingMgr::instance().getMode()) {
|
||||||
|
lock_ = std::unique_lock<std::mutex>(mutex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
CSCallbackSetList::addCallbackSet(const std::string& name,
|
CSCallbackSetList::addCallbackSet(const std::string& name,
|
||||||
const CSCallbackSet::Callback& check_cb,
|
const CSCallbackSet::Callback& check_cb,
|
||||||
|
@@ -108,7 +108,8 @@ private:
|
|||||||
///
|
///
|
||||||
/// This singleton class holds the multi-threading mode.
|
/// This singleton class holds the multi-threading mode.
|
||||||
///
|
///
|
||||||
/// The standard way to use it is:
|
/// See the @ref MultiThreadingLock class for a standard way of protecting code
|
||||||
|
/// with a mutex. Or if you want to make it look like you're writing more code:
|
||||||
/// @code
|
/// @code
|
||||||
/// if (MultiThreadingMgr::instance().getMode()) {
|
/// if (MultiThreadingMgr::instance().getMode()) {
|
||||||
/// multi-threaded code
|
/// multi-threaded code
|
||||||
@@ -325,6 +326,20 @@ private:
|
|||||||
CSCallbackSetList cs_callbacks_;
|
CSCallbackSetList cs_callbacks_;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/// @brief RAII lock object to protect the code in the same scope with a mutex
|
||||||
|
struct MultiThreadingLock {
|
||||||
|
/// @brief Constructor locks the mutex if multi-threading is enabled.
|
||||||
|
///
|
||||||
|
/// The lock is automatically unlocked in the default destructor.
|
||||||
|
///
|
||||||
|
/// @param mutex the mutex to be locked
|
||||||
|
MultiThreadingLock(std::mutex& mutex);
|
||||||
|
|
||||||
|
private:
|
||||||
|
/// @brief object keeping the mutex locked for its entire lifetime
|
||||||
|
std::unique_lock<std::mutex> lock_;
|
||||||
|
};
|
||||||
|
|
||||||
/// @note: everything here MUST be used ONLY from the main thread.
|
/// @note: everything here MUST be used ONLY from the main thread.
|
||||||
/// When called from a thread of the pool it can deadlock.
|
/// When called from a thread of the pool it can deadlock.
|
||||||
|
|
||||||
|
@@ -324,6 +324,40 @@ TEST(MultiThreadingMgrTest, criticalSection) {
|
|||||||
MultiThreadingMgr::instance().apply(false, 0, 0);
|
MultiThreadingMgr::instance().apply(false, 0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// @brief Checks that the lock works only when multi-threading is enabled and
|
||||||
|
/// only during its lifetime.
|
||||||
|
TEST(MultiThreadingLockTest, scope) {
|
||||||
|
// Check that the mutex is unlocked by default at first.
|
||||||
|
std::mutex mutex;
|
||||||
|
ASSERT_TRUE(mutex.try_lock());
|
||||||
|
mutex.unlock();
|
||||||
|
|
||||||
|
EXPECT_NO_THROW(MultiThreadingMgr::instance().setMode(false));
|
||||||
|
|
||||||
|
// Check that the lock does not locks the mutex if multi-threading is disabled.
|
||||||
|
{
|
||||||
|
MultiThreadingLock lock(mutex);
|
||||||
|
ASSERT_TRUE(mutex.try_lock());
|
||||||
|
mutex.unlock();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check that the mutex is still unlocked when the lock goes out of scope.
|
||||||
|
ASSERT_TRUE(mutex.try_lock());
|
||||||
|
mutex.unlock();
|
||||||
|
|
||||||
|
EXPECT_NO_THROW(MultiThreadingMgr::instance().setMode(true));
|
||||||
|
|
||||||
|
// Check that the lock actively locks the mutex if multi-threading is enabled.
|
||||||
|
{
|
||||||
|
MultiThreadingLock lock(mutex);
|
||||||
|
ASSERT_FALSE(mutex.try_lock());
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check that the mutex is unlocked when the lock goes out of scope.
|
||||||
|
ASSERT_TRUE(mutex.try_lock());
|
||||||
|
mutex.unlock();
|
||||||
|
}
|
||||||
|
|
||||||
/// @brief Test fixture for exercised CriticalSection callbacks.
|
/// @brief Test fixture for exercised CriticalSection callbacks.
|
||||||
class CriticalSectionCallbackTest : public ::testing::Test {
|
class CriticalSectionCallbackTest : public ::testing::Test {
|
||||||
public:
|
public:
|
||||||
|
Reference in New Issue
Block a user