#pragma once #include #include #include #include #include #include namespace brynet { namespace base { class WaitGroup : public NonCopyable { public: typedef std::shared_ptr Ptr; static Ptr Create() { struct make_shared_enabler : public WaitGroup {}; return std::make_shared(); } public: void add(int i = 1) { mCounter += i; } void done() { mCounter--; mCond.notify_all(); } void wait() { std::unique_lock l(mMutex); mCond.wait(l, [&] { return mCounter <= 0; }); } template void wait(const std::chrono::duration& timeout) { std::unique_lock l(mMutex); mCond.wait_for(l, timeout, [&] { return mCounter <= 0; }); } private: WaitGroup() : mCounter(0) { } virtual ~WaitGroup() = default; private: std::mutex mMutex; std::atomic mCounter; std::condition_variable mCond; }; } }