Improve BlockingQueue and add SyncQueue
Changes to BlockingQueue:
- Change BlockingQueue to be list-backed instead of vector-backed so
that removals are O(1) instead of O(N).
- Rename erase to erase_if.
- Make providing a fixed capacity at construction optional.
- Add emplace function to push and construct element in-place.
- Add popWithTimeout function.
Bug: 275726706
Test: atest inputflinger_tests
Change-Id: I1be02b0887df2c21b28f4f1cb43a8e208d996a87
diff --git a/services/inputflinger/SyncQueue.h b/services/inputflinger/SyncQueue.h
new file mode 100644
index 0000000..62efd55
--- /dev/null
+++ b/services/inputflinger/SyncQueue.h
@@ -0,0 +1,53 @@
+/*
+ * Copyright 2023 The Android Open Source Project
+ *
+ * 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
+ *
+ * http://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.
+ */
+
+#pragma once
+
+#include <utils/threads.h>
+#include <list>
+#include <mutex>
+#include <optional>
+
+namespace android {
+
+/** A thread-safe FIFO queue. */
+template <class T>
+class SyncQueue {
+public:
+ /** Retrieve and remove the oldest object. Returns std::nullopt if the queue is empty. */
+ std::optional<T> pop() {
+ std::scoped_lock lock(mLock);
+ if (mQueue.empty()) {
+ return {};
+ }
+ T t = std::move(mQueue.front());
+ mQueue.erase(mQueue.begin());
+ return t;
+ };
+
+ /** Add a new object to the queue. */
+ template <class... Args>
+ void push(Args&&... args) {
+ std::scoped_lock lock(mLock);
+ mQueue.emplace_back(args...);
+ };
+
+private:
+ std::mutex mLock;
+ std::list<T> mQueue GUARDED_BY(mLock);
+};
+
+} // namespace android