MOTION  0.01
Framework for mixed-protocol multi-party computation
locked_queue.h
Go to the documentation of this file.
1 // MIT License
2 //
3 // Copyright (c) 2019 Lennart Braun
4 //
5 // Permission is hereby granted, free of charge, to any person obtaining a copy
6 // of this software and associated documentation files (the "Software"), to deal
7 // in the Software without restriction, including without limitation the rights
8 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 // copies of the Software, and to permit persons to whom the Software is
10 // furnished to do so, subject to the following conditions:
11 //
12 // The above copyright notice and this permission notice shall be included in all
13 // copies or substantial portions of the Software.
14 //
15 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 // SOFTWARE.
22 
23 #ifndef LOCKED_QUEUE_HPP
24 #define LOCKED_QUEUE_HPP
25 
26 #include <condition_variable>
27 #include <future>
28 #include <iostream>
29 #include <mutex>
30 #include <optional>
31 #include <queue>
32 
33 namespace encrypto::motion {
34 
38 template <typename T>
39 class LockedQueue {
40  public:
44  bool empty() const {
45  std::lock_guard<std::timed_mutex> lock(mutex_);
46  return queue_.empty();
47  }
48 
52  void enqueue(const T& item) {
53  {
54  std::scoped_lock<std::timed_mutex> lock(mutex_);
55  queue_.push(item);
56  }
57  condition_variable_.notify_one();
58  }
59 
60  void enqueue(T&& item) {
61  {
62  std::scoped_lock<std::timed_mutex> lock(mutex_);
63  queue_.push(item);
64  }
65  condition_variable_.notify_one();
66  }
67 
71  T dequeue() {
72  std::unique_lock<std::timed_mutex> lock(mutex_);
73  if (queue_.empty()) {
74  condition_variable_.wait(lock, [this] { return !this->queue_.empty(); });
75  }
76  auto item = queue_.front();
77  queue_.pop();
78  lock.unlock();
79  return item;
80  }
81 
85  template <typename Tick, typename Period>
86  std::optional<T> dequeue(const std::chrono::duration<Tick, Period>& duration) {
87  std::unique_lock<std::timed_mutex> lock(mutex_, duration);
88  if (!lock) {
89  return std::optional<T>(std::nullopt);
90  }
91  // lock is aquired
92  if (!queue_.empty()) {
93  auto item = queue_.front();
94  queue_.pop();
95  lock.unlock();
96  return std::optional(item);
97  }
98  // queue is currently empty
99  if (!condition_variable_.wait_for(lock, duration, [this] { return !this->queue_.empty(); })) {
100  lock.unlock();
101  return std::optional<T>(std::nullopt);
102  }
103  // queue contains an item
104  auto item = queue_.front();
105  queue_.pop();
106  lock.unlock();
107  return std::optional(item);
108  }
109 
113  template <typename Tick, typename Period>
114  std::queue<T> BatchDeque(const std::chrono::duration<Tick, Period>& duration) {
115  std::queue<T> output;
116  std::unique_lock<std::timed_mutex> lock(mutex_, duration);
117 
118  // we got the lock in time
119  if (lock) {
120  // let's wait for new entries
121  if (queue_.empty()) {
122  // there are some entries now
123  if (condition_variable_.wait_for(lock, duration,
124  [this] { return !this->queue_.empty(); })) {
125  std::swap(queue_, output);
126  }
127  }
128  // queue is not empty
129  else {
130  std::swap(queue_, output);
131  }
132  lock.unlock();
133  }
134  return output;
135  }
136 
137  private:
138  std::queue<T> queue_;
139  mutable std::timed_mutex mutex_;
140  std::condition_variable_any condition_variable_;
141 };
142 
143 } // namespace encrypto::motion
144 
145 #endif // LOCKED_QUEUE_HPP
encrypto::motion::LockedQueue::dequeue
std::optional< T > dequeue(const std::chrono::duration< Tick, Period > &duration)
Definition: locked_queue.h:86
encrypto::motion::LockedQueue::dequeue
T dequeue()
Definition: locked_queue.h:71
encrypto::motion::LockedQueue::enqueue
void enqueue(T &&item)
Definition: locked_queue.h:60
encrypto::motion::LockedQueue
Definition: locked_queue.h:39
encrypto::motion::LockedQueue::BatchDeque
std::queue< T > BatchDeque(const std::chrono::duration< Tick, Period > &duration)
Definition: locked_queue.h:114
encrypto::motion
Definition: algorithm_description.cpp:35
encrypto::motion::LockedQueue::empty
bool empty() const
Definition: locked_queue.h:44
encrypto::motion::swap
void swap(ReusablePromise< R, MutexType, ConditionVariableType > &lhs, ReusablePromise< R, MutexType, ConditionVariableType > &rhs) noexcept
Definition: reusable_future.h:270
encrypto::motion::LockedQueue::enqueue
void enqueue(const T &item)
Definition: locked_queue.h:52