SynchronizedQueue.h 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113
  1. /*
  2. * Copyright (C) 2016 The Android Open Source Project
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License");
  5. * you may not use this file except in compliance with the License.
  6. * You may obtain a copy of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License.
  15. */
  16. #ifndef ANDROID_HIDL_SYNCHRONIZED_QUEUE_H
  17. #define ANDROID_HIDL_SYNCHRONIZED_QUEUE_H
  18. #include <condition_variable>
  19. #include <mutex>
  20. #include <queue>
  21. #include <thread>
  22. namespace android {
  23. namespace hardware {
  24. namespace details {
  25. /* Threadsafe queue.
  26. */
  27. template <typename T>
  28. struct SynchronizedQueue {
  29. SynchronizedQueue(size_t limit);
  30. /* Gets an item from the front of the queue.
  31. *
  32. * Blocks until the item is available.
  33. */
  34. T wait_pop();
  35. /* Puts an item onto the end of the queue.
  36. */
  37. bool push(const T& item);
  38. /* Gets the size of the array.
  39. */
  40. size_t size();
  41. std::unique_lock<std::mutex> lock() {
  42. return std::unique_lock<std::mutex>(mMutex);
  43. }
  44. bool isInitializedLocked() {
  45. return mInitialized;
  46. }
  47. void setInitializedLocked(bool isInitialized) {
  48. mInitialized = isInitialized;
  49. }
  50. private:
  51. std::condition_variable mCondition;
  52. std::mutex mMutex;
  53. std::queue<T> mQueue;
  54. const size_t mQueueLimit;
  55. bool mInitialized = false;
  56. };
  57. template <typename T>
  58. SynchronizedQueue<T>::SynchronizedQueue(size_t limit) : mQueueLimit(limit) {
  59. }
  60. template <typename T>
  61. T SynchronizedQueue<T>::wait_pop() {
  62. std::unique_lock<std::mutex> lock(mMutex);
  63. mCondition.wait(lock, [this]{
  64. return !this->mQueue.empty();
  65. });
  66. T item = mQueue.front();
  67. mQueue.pop();
  68. return item;
  69. }
  70. template <typename T>
  71. bool SynchronizedQueue<T>::push(const T &item) {
  72. bool success;
  73. {
  74. std::unique_lock<std::mutex> lock(mMutex);
  75. if (mQueue.size() < mQueueLimit) {
  76. mQueue.push(item);
  77. success = true;
  78. } else {
  79. success = false;
  80. }
  81. }
  82. mCondition.notify_one();
  83. return success;
  84. }
  85. template <typename T>
  86. size_t SynchronizedQueue<T>::size() {
  87. std::unique_lock<std::mutex> lock(mMutex);
  88. return mQueue.size();
  89. }
  90. } // namespace details
  91. } // namespace hardware
  92. } // namespace android
  93. #endif // ANDROID_HIDL_SYNCHRONIZED_QUEUE_H