diff options
Diffstat (limited to 'osdep/BlockingQueue.hpp')
-rw-r--r-- | osdep/BlockingQueue.hpp | 57 |
1 files changed, 50 insertions, 7 deletions
diff --git a/osdep/BlockingQueue.hpp b/osdep/BlockingQueue.hpp index 6172f4da..351a095a 100644 --- a/osdep/BlockingQueue.hpp +++ b/osdep/BlockingQueue.hpp @@ -1,6 +1,6 @@ /* * ZeroTier One - Network Virtualization Everywhere - * Copyright (C) 2011-2016 ZeroTier, Inc. https://www.zerotier.com/ + * Copyright (C) 2011-2018 ZeroTier, Inc. https://www.zerotier.com/ * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -14,6 +14,14 @@ * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * -- + * + * You can be released from the requirements of the license by purchasing + * a commercial license. Buying such a license is mandatory as soon as you + * develop commercial closed-source software that incorporates or links + * directly against ZeroTier software without disclosing the source code + * of your own application. */ #ifndef ZT_BLOCKINGQUEUE_HPP @@ -22,6 +30,7 @@ #include <queue> #include <mutex> #include <condition_variable> +#include <chrono> namespace ZeroTier { @@ -34,7 +43,7 @@ template <class T> class BlockingQueue { public: - BlockingQueue(void) {} + BlockingQueue(void) : r(true) {} inline void post(T t) { @@ -43,19 +52,53 @@ public: c.notify_one(); } - inline T get(void) + inline void stop(void) + { + std::lock_guard<std::mutex> lock(m); + r = false; + c.notify_all(); + } + + inline bool get(T &value) { std::unique_lock<std::mutex> lock(m); - while(q.empty()) + if (!r) return false; + while (q.empty()) { c.wait(lock); - T val = q.front(); + if (!r) return false; + } + value = q.front(); + q.pop(); + return true; + } + + enum TimedWaitResult + { + OK, + TIMED_OUT, + STOP + }; + + inline TimedWaitResult get(T &value,const unsigned long ms) + { + const std::chrono::milliseconds ms2{ms}; + std::unique_lock<std::mutex> lock(m); + if (!r) return STOP; + while (q.empty()) { + if (c.wait_for(lock,ms2) == std::cv_status::timeout) + return ((r) ? TIMED_OUT : STOP); + else if (!r) + return STOP; + } + value = q.front(); q.pop(); - return val; + return OK; } private: + volatile bool r; std::queue<T> q; - mutable std::mutex m; + std::mutex m; std::condition_variable c; }; |