github.com/igggame/nebulas-go@v2.1.0+incompatible/nbre/util/wakeable_queue.h (about) 1 // Copyright (C) 2018 go-nebulas authors 2 // 3 // This file is part of the go-nebulas library. 4 // 5 // the go-nebulas library is free software: you can redistribute it and/or 6 // modify 7 // it under the terms of the GNU General Public License as published by 8 // the Free Software Foundation, either version 3 of the License, or // (at your 9 // option) any later version. 10 // 11 // the go-nebulas library is distributed in the hope that it will be useful, 12 // but WITHOUT ANY WARRANTY; without even the implied warranty of 13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 // GNU General Public License for more details. 15 // 16 // You should have received a copy of the GNU General Public License 17 // along with the go-nebulas library. If not, see 18 // <http://www.gnu.org/licenses/>. 19 // 20 #pragma once 21 #include "common/common.h" 22 #include <condition_variable> 23 #include <queue> 24 25 namespace neb { 26 namespace util { 27 28 template <typename T> class wakeable_queue { 29 public: 30 typedef std::queue<T> queue_t; 31 wakeable_queue() = default; 32 33 void push_back(const typename queue_t::value_type &op) { 34 std::unique_lock<std::mutex> _l(m_mutex); 35 bool was_empty = m_queue.empty(); 36 m_queue.push(op); 37 _l.unlock(); 38 if (was_empty) { 39 m_cond_var.notify_all(); 40 } 41 } 42 43 std::pair<bool, typename queue_t::value_type> pop_front() { 44 std::unique_lock<std::mutex> _l(m_mutex); 45 bool is_empty = m_queue.empty(); 46 if (is_empty) { 47 m_cond_var.wait(_l); 48 } 49 if (m_queue.empty()) { 50 return std::make_pair(false, typename queue_t::value_type()); 51 } 52 auto ret = m_queue.front(); 53 m_queue.pop(); 54 return std::make_pair(true, ret); 55 } 56 57 std::pair<bool, typename queue_t::value_type> try_pop_front() { 58 std::unique_lock<std::mutex> _l(m_mutex); 59 if (m_queue.empty()) { 60 return std::make_pair(false, typename queue_t::value_type()); 61 } 62 auto ret = m_queue.front(); 63 m_queue.pop(); 64 return std::make_pair(true, ret); 65 } 66 67 size_t size() const { 68 std::unique_lock<std::mutex> _l(m_mutex); 69 return m_queue.size(); 70 } 71 72 bool empty() const { 73 std::unique_lock<std::mutex> _l(m_mutex); 74 return m_queue.empty(); 75 } 76 77 void wake_up_if_empty() { 78 std::unique_lock<std::mutex> _l(m_mutex); 79 if (m_queue.empty()) { 80 _l.unlock(); 81 m_cond_var.notify_one(); 82 } 83 } 84 85 protected: 86 queue_t m_queue; 87 mutable std::mutex m_mutex; 88 std::condition_variable m_cond_var; 89 }; 90 } // namespace util 91 92 } // namespace neb