diff options
Diffstat (limited to 'Utilities/cmcppdap/src/chan.h')
-rw-r--r-- | Utilities/cmcppdap/src/chan.h | 90 |
1 files changed, 90 insertions, 0 deletions
diff --git a/Utilities/cmcppdap/src/chan.h b/Utilities/cmcppdap/src/chan.h new file mode 100644 index 0000000..f2345e9 --- /dev/null +++ b/Utilities/cmcppdap/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 |