Files
espcpputils/src/lockingqueue.h

72 lines
1.4 KiB
C
Raw Normal View History

2021-01-04 20:11:38 +01:00
#pragma once
// system includes
#include <optional>
2021-01-08 02:36:01 +01:00
#include <queue>
2021-01-04 20:11:38 +01:00
// espressif includes
#include <freertos/FreeRTOS.h>
#include <freertos/semphr.h>
// local includes
#include "delayedconstruction.h"
2021-05-04 04:43:29 +02:00
#include "wrappers/mutex_semaphore.h"
#include "lockhelper.h"
2021-01-04 20:11:38 +01:00
namespace espcpputils {
template<typename T>
class LockingQueue
{
public:
void push(const T &val);
void push(T &&val);
std::optional<T> tryPop();
void clear();
std::size_t size() const { return m_size; }
private:
2021-05-04 04:43:29 +02:00
espcpputils::mutex_semaphore m_lock;
2021-01-08 02:36:01 +01:00
std::queue<T> m_queue;
2021-01-04 20:11:38 +01:00
std::size_t m_size{}; // double-buffered to allow for reading without taking a lock
};
template<typename T>
void LockingQueue<T>::push(const T &val)
{
2021-05-04 04:43:29 +02:00
LockHelper helper{m_lock.handle};
2021-01-08 02:36:01 +01:00
m_queue.push(val);
2021-01-04 20:11:38 +01:00
m_size = m_queue.size();
}
template<typename T>
void LockingQueue<T>::push(T &&val)
{
2021-05-04 04:43:29 +02:00
LockHelper helper{m_lock.handle};
2021-01-08 02:36:01 +01:00
m_queue.emplace(std::move(val));
2021-01-04 20:11:38 +01:00
m_size = m_queue.size();
}
template<typename T>
std::optional<T> LockingQueue<T>::tryPop()
{
2021-05-04 04:43:29 +02:00
LockHelper helper{m_lock.handle};
2021-01-04 20:11:38 +01:00
if (m_queue.empty())
return std::nullopt;
std::optional<T> temp = std::move(m_queue.front());
2021-01-08 02:36:01 +01:00
m_queue.pop();
2021-01-04 20:11:38 +01:00
m_size = m_queue.size();
return temp;
}
template<typename T>
void LockingQueue<T>::clear()
{
2021-05-04 04:43:29 +02:00
LockHelper helper{m_lock.handle};
2021-02-28 20:37:23 +01:00
m_queue = {};
2021-01-04 20:11:38 +01:00
}
} // namespace espcpputils