mirror of
https://github.com/Icinga/icinga2.git
synced 2025-07-22 13:14:32 +02:00
Introduce WaitGroup and StoppableWaitGroup
This commit is contained in:
parent
69d2a0442a
commit
18fb93fc11
@ -87,6 +87,7 @@ set(base_SOURCES
|
||||
unixsocket.cpp unixsocket.hpp
|
||||
utility.cpp utility.hpp
|
||||
value.cpp value.hpp value-operators.cpp
|
||||
wait-group.cpp wait-group.hpp
|
||||
win32.hpp
|
||||
workqueue.cpp workqueue.hpp
|
||||
)
|
||||
|
38
lib/base/wait-group.cpp
Normal file
38
lib/base/wait-group.cpp
Normal file
@ -0,0 +1,38 @@
|
||||
/* Icinga 2 | (c) 2025 Icinga GmbH | GPLv2+ */
|
||||
|
||||
#include "base/wait-group.hpp"
|
||||
|
||||
using namespace icinga;
|
||||
|
||||
bool StoppableWaitGroup::try_lock_shared()
|
||||
{
|
||||
std::unique_lock lock (m_Mutex);
|
||||
|
||||
if (m_Stopped) {
|
||||
return false;
|
||||
}
|
||||
|
||||
++m_SharedLocks;
|
||||
return true;
|
||||
}
|
||||
|
||||
void StoppableWaitGroup::unlock_shared()
|
||||
{
|
||||
std::unique_lock lock (m_Mutex);
|
||||
|
||||
if (!--m_SharedLocks && m_Stopped) {
|
||||
lock.unlock();
|
||||
m_CV.notify_all();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Disallow new shared locks, wait for all existing ones.
|
||||
*/
|
||||
void StoppableWaitGroup::Join()
|
||||
{
|
||||
std::unique_lock lock (m_Mutex);
|
||||
|
||||
m_Stopped = true;
|
||||
m_CV.wait(lock, [this] { return !m_SharedLocks; });
|
||||
}
|
54
lib/base/wait-group.hpp
Normal file
54
lib/base/wait-group.hpp
Normal file
@ -0,0 +1,54 @@
|
||||
/* Icinga 2 | (c) 2025 Icinga GmbH | GPLv2+ */
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "base/object.hpp"
|
||||
#include <condition_variable>
|
||||
#include <cstdint>
|
||||
#include <mutex>
|
||||
|
||||
namespace icinga
|
||||
{
|
||||
|
||||
/**
|
||||
* A synchronization interface that allows concurrent shared locking.
|
||||
*
|
||||
* @ingroup base
|
||||
*/
|
||||
class WaitGroup : public Object
|
||||
{
|
||||
public:
|
||||
DECLARE_PTR_TYPEDEFS(WaitGroup);
|
||||
|
||||
virtual bool try_lock_shared() = 0;
|
||||
virtual void unlock_shared() = 0;
|
||||
};
|
||||
|
||||
/**
|
||||
* A thread-safe wait group that can be stopped to prevent further shared locking.
|
||||
*
|
||||
* @ingroup base
|
||||
*/
|
||||
class StoppableWaitGroup : public WaitGroup
|
||||
{
|
||||
public:
|
||||
DECLARE_PTR_TYPEDEFS(StoppableWaitGroup);
|
||||
|
||||
StoppableWaitGroup() = default;
|
||||
StoppableWaitGroup(const StoppableWaitGroup&) = delete;
|
||||
StoppableWaitGroup(StoppableWaitGroup&&) = delete;
|
||||
StoppableWaitGroup& operator=(const StoppableWaitGroup&) = delete;
|
||||
StoppableWaitGroup& operator=(StoppableWaitGroup&&) = delete;
|
||||
|
||||
bool try_lock_shared() override;
|
||||
void unlock_shared() override;
|
||||
void Join();
|
||||
|
||||
private:
|
||||
std::mutex m_Mutex;
|
||||
std::condition_variable m_CV;
|
||||
uint_fast32_t m_SharedLocks = 0;
|
||||
bool m_Stopped = false;
|
||||
};
|
||||
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user