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
|