rcpp_framework/libs/brynet/base/WaitGroup.hpp

68 lines
1.2 KiB
C++
Raw Normal View History

2020-11-24 15:41:18 +01:00
#pragma once
#include <atomic>
#include <brynet/base/NonCopyable.hpp>
2021-04-30 16:10:14 +02:00
#include <chrono>
#include <condition_variable>
#include <memory>
#include <mutex>
2020-11-24 15:41:18 +01:00
namespace brynet { namespace base {
2021-04-30 16:10:14 +02:00
class WaitGroup : public NonCopyable
{
public:
typedef std::shared_ptr<WaitGroup> Ptr;
2020-11-24 15:41:18 +01:00
2021-04-30 16:10:14 +02:00
static Ptr Create()
{
struct make_shared_enabler : public WaitGroup
2020-11-24 15:41:18 +01:00
{
2021-04-30 16:10:14 +02:00
};
return std::make_shared<make_shared_enabler>();
}
2020-11-24 15:41:18 +01:00
2021-04-30 16:10:14 +02:00
public:
void add(int i = 1)
{
mCounter += i;
}
2020-11-24 15:41:18 +01:00
2021-04-30 16:10:14 +02:00
void done()
{
mCounter--;
mCond.notify_all();
}
2020-11-24 15:41:18 +01:00
2021-04-30 16:10:14 +02:00
void wait()
{
std::unique_lock<std::mutex> l(mMutex);
mCond.wait(l, [&] {
return mCounter <= 0;
});
}
2020-11-24 15:41:18 +01:00
2021-04-30 16:10:14 +02:00
template<class Rep, class Period>
void wait(const std::chrono::duration<Rep, Period>& timeout)
{
std::unique_lock<std::mutex> l(mMutex);
mCond.wait_for(l, timeout, [&] {
return mCounter <= 0;
});
}
2020-11-24 15:41:18 +01:00
2021-04-30 16:10:14 +02:00
private:
WaitGroup()
: mCounter(0)
{
}
2020-11-24 15:41:18 +01:00
2021-04-30 16:10:14 +02:00
virtual ~WaitGroup() = default;
2020-11-24 15:41:18 +01:00
2021-04-30 16:10:14 +02:00
private:
std::mutex mMutex;
std::atomic<int> mCounter;
std::condition_variable mCond;
};
}}// namespace brynet::base