mirror of
https://github.com/Icinga/icinga2.git
synced 2025-07-22 21:24:41 +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
|
unixsocket.cpp unixsocket.hpp
|
||||||
utility.cpp utility.hpp
|
utility.cpp utility.hpp
|
||||||
value.cpp value.hpp value-operators.cpp
|
value.cpp value.hpp value-operators.cpp
|
||||||
|
wait-group.cpp wait-group.hpp
|
||||||
win32.hpp
|
win32.hpp
|
||||||
workqueue.cpp workqueue.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