summaryrefslogtreecommitdiffstats
path: root/Utilities/cmcppdap/src/chan.h
diff options
context:
space:
mode:
Diffstat (limited to 'Utilities/cmcppdap/src/chan.h')
-rw-r--r--Utilities/cmcppdap/src/chan.h90
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