Prevent exceptions being thrown in TSQueue

TSQueue's top() and top_and_pop() now return std::optional<T> instead of
just T.
This commit is contained in:
Stephen Seo 2019-09-03 15:15:09 +09:00
parent 150deb7e5c
commit 05cb45ca14
3 changed files with 17 additions and 10 deletions

View file

@ -6,6 +6,7 @@
#include <cstdlib> #include <cstdlib>
#include <memory> #include <memory>
#include <mutex> #include <mutex>
#include <optional>
#include <RB/RingBuffer.hpp> #include <RB/RingBuffer.hpp>
@ -23,9 +24,9 @@ class TSQueue {
TSQueue &operator=(TSQueue &&other); TSQueue &operator=(TSQueue &&other);
bool push(const T &data); bool push(const T &data);
T top(); std::optional<T> top();
bool pop(); bool pop();
T top_and_pop(); std::optional<T> top_and_pop();
void clear(); void clear();
void changeCapacity(unsigned int newCapacity); void changeCapacity(unsigned int newCapacity);
unsigned int size(); unsigned int size();
@ -81,9 +82,12 @@ bool TSQueue<T>::push(const T &data) {
} }
template <typename T> template <typename T>
T TSQueue<T>::top() { std::optional<T> TSQueue<T>::top() {
std::lock_guard<std::mutex> lock(mutex); std::lock_guard<std::mutex> lock(mutex);
T value = rb.top(); std::optional<T> value = std::nullopt;
if(!rb.empty()) {
value = rb.top();
}
return value; return value;
} }
@ -98,10 +102,13 @@ bool TSQueue<T>::pop() {
} }
template <typename T> template <typename T>
T TSQueue<T>::top_and_pop() { std::optional<T> TSQueue<T>::top_and_pop() {
std::lock_guard<std::mutex> lock(mutex); std::lock_guard<std::mutex> lock(mutex);
T value = rb.top(); std::optional<T> value = std::nullopt;
rb.pop(); if(!rb.empty()) {
value = rb.top();
rb.pop();
}
return value; return value;
} }

View file

@ -496,11 +496,11 @@ void UDPC_update(UDPC_HContext ctx) {
bool isResending = false; bool isResending = false;
if(!iter->second.priorityPkts.empty()) { if(!iter->second.priorityPkts.empty()) {
// TODO verify getting struct copy is valid // TODO verify getting struct copy is valid
pInfo = iter->second.priorityPkts.top(); pInfo = std::move(iter->second.priorityPkts.top().value());
iter->second.priorityPkts.pop(); iter->second.priorityPkts.pop();
isResending = true; isResending = true;
} else { } else {
pInfo = iter->second.sendPkts.top(); pInfo = std::move(iter->second.sendPkts.top().value());
iter->second.sendPkts.pop(); iter->second.sendPkts.pop();
} }
std::unique_ptr<char[]> buf = std::make_unique<char[]>(20 + pInfo.dataSize); std::unique_ptr<char[]> buf = std::make_unique<char[]>(20 + pInfo.dataSize);

View file

@ -133,7 +133,7 @@ TEST(TSQueue, Concurrent)
int top; int top;
for(int i = 0; i < 4; ++i) { for(int i = 0; i < 4; ++i) {
top = q.top(); top = q.top().value();
EXPECT_TRUE(q.pop()); EXPECT_TRUE(q.pop());
EXPECT_EQ(q.size(), 3 - i); EXPECT_EQ(q.size(), 3 - i);
printf("%d ", top); printf("%d ", top);