diff options
author | cppdap Upstream <kwrobot@kitware.com> | 2023-05-25 23:20:21 (GMT) |
---|---|---|
committer | Brad King <brad.king@kitware.com> | 2023-05-26 13:33:55 (GMT) |
commit | 1daeefc37856c209718b406dcb86d44519393dd1 (patch) | |
tree | fad61ae09ad74d5f21fedaeb80308ff494af1751 /src/chan.h | |
download | CMake-1daeefc37856c209718b406dcb86d44519393dd1.zip CMake-1daeefc37856c209718b406dcb86d44519393dd1.tar.gz CMake-1daeefc37856c209718b406dcb86d44519393dd1.tar.bz2 |
cppdap 2023-05-26 (03cc1867)
Code extracted from:
https://github.com/google/cppdap.git
at commit 03cc18678ed2ed8b2424ec99dee7e4655d876db5 (03cc18678ed2ed8b2424ec99dee7e4655d876db5).
Diffstat (limited to 'src/chan.h')
-rw-r--r-- | src/chan.h | 90 |
1 files changed, 90 insertions, 0 deletions
diff --git a/src/chan.h b/src/chan.h new file mode 100644 index 0000000..f2345e9 --- /dev/null +++ b/src/chan.h @@ -0,0 +1,90 @@ +// Copyright 2019 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef dap_chan_h +#define dap_chan_h + +#include "dap/optional.h" + +#include <condition_variable> +#include <mutex> +#include <queue> + +namespace dap { + +template <typename T> +struct Chan { + public: + void reset(); + void close(); + optional<T> take(); + void put(T&& in); + void put(const T& in); + + private: + bool closed = false; + std::queue<T> queue; + std::condition_variable cv; + std::mutex mutex; +}; + +template <typename T> +void Chan<T>::reset() { + std::unique_lock<std::mutex> lock(mutex); + queue = {}; + closed = false; +} + +template <typename T> +void Chan<T>::close() { + std::unique_lock<std::mutex> lock(mutex); + closed = true; + cv.notify_all(); +} + +template <typename T> +optional<T> Chan<T>::take() { + std::unique_lock<std::mutex> lock(mutex); + cv.wait(lock, [&] { return queue.size() > 0 || closed; }); + if (queue.size() == 0) { + return optional<T>(); + } + auto out = std::move(queue.front()); + queue.pop(); + return optional<T>(std::move(out)); +} + +template <typename T> +void Chan<T>::put(T&& in) { + std::unique_lock<std::mutex> lock(mutex); + auto notify = queue.size() == 0 && !closed; + queue.push(std::move(in)); + if (notify) { + cv.notify_all(); + } +} + +template <typename T> +void Chan<T>::put(const T& in) { + std::unique_lock<std::mutex> lock(mutex); + auto notify = queue.size() == 0 && !closed; + queue.push(in); + if (notify) { + cv.notify_all(); + } +} + +} // namespace dap + +#endif // dap_chan_h |