// Copyright 2015, Tobias Hermann and the FunctionalPlus contributors. // https://github.com/Dobiasd/FunctionalPlus // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) #pragma once #include #include #include #include namespace fplus { // A thread-safe queue. template class queue { public: queue() : queue_(), mutex_(), cond_() {} fplus::maybe pop() { std::unique_lock lock(mutex_); if (queue_.empty()) { return {}; } auto item = queue_.front(); queue_.pop_front(); return item; } void push(const T& item) { { std::unique_lock lock(mutex_); queue_.push_back(item); } cond_.notify_one(); } std::vector pop_all() { std::unique_lock mlock(mutex_); const auto result = fplus::convert_container>(queue_); queue_.clear(); return result; } std::vector wait_and_pop_all() { std::unique_lock mlock(mutex_); cond_.wait(mlock, [&]() -> bool { return !queue_.empty(); }); const auto result = fplus::convert_container>(queue_); queue_.clear(); return result; } std::vector wait_for_and_pop_all(std::int64_t max_wait_time_us) { std::unique_lock mlock(mutex_); const auto t = std::chrono::microseconds{ max_wait_time_us }; cond_.wait_for(mlock, t, [&]() -> bool { return !queue_.empty(); }); const auto result = fplus::convert_container>(queue_); queue_.clear(); return result; } private: std::deque queue_; std::mutex mutex_; std::condition_variable cond_; }; } // namespace fplus