new cspot/bell

This commit is contained in:
philippe44
2023-05-06 23:50:26 +02:00
parent e0e7e718ba
commit 8bad480112
163 changed files with 6611 additions and 6739 deletions

View File

@@ -1,117 +1,101 @@
#ifndef BELL_QUEUE_H
#define BELL_QUEUE_H
#include <queue>
#include <atomic>
#include <condition_variable>
#include <atomic>
#include <queue>
namespace bell
{
template <typename dataType>
class Queue
{
private:
/// Queue
std::queue<dataType> m_queue;
/// Mutex to controll multiple access
mutable std::mutex m_mutex;
/// Conditional variable used to fire event
std::condition_variable m_cv;
/// Atomic variable used to terminate immediately wpop and wtpop functions
std::atomic<bool> m_forceExit = false;
namespace bell {
template <typename dataType>
class Queue {
private:
/// Queue
std::queue<dataType> m_queue;
/// Mutex to controll multiple access
mutable std::mutex m_mutex;
/// Conditional variable used to fire event
std::condition_variable m_cv;
/// Atomic variable used to terminate immediately wpop and wtpop functions
std::atomic<bool> m_forceExit = false;
public:
/// <summary> Add a new element in the queue. </summary>
/// <param name="data"> New element. </param>
void push(dataType const &data)
{
m_forceExit.store(false);
std::unique_lock<std::mutex> lk(m_mutex);
m_queue.push(data);
lk.unlock();
m_cv.notify_one();
}
/// <summary> Check queue empty. </summary>
/// <returns> True if the queue is empty. </returns>
bool isEmpty() const
{
std::unique_lock<std::mutex> lk(m_mutex);
return m_queue.empty();
}
/// <summary> Pop element from queue. </summary>
/// <param name="popped_value"> [in,out] Element. </param>
/// <returns> false if the queue is empty. </returns>
bool pop(dataType &popped_value)
{
std::unique_lock<std::mutex> lk(m_mutex);
if (m_queue.empty())
{
return false;
}
else
{
popped_value = m_queue.front();
m_queue.pop();
return true;
}
}
/// <summary> Wait and pop an element in the queue. </summary>
/// <param name="popped_value"> [in,out] Element. </param>
/// <returns> False for forced exit. </returns>
bool wpop(dataType &popped_value)
{
std::unique_lock<std::mutex> lk(m_mutex);
m_cv.wait(lk, [&]() -> bool
{ return !m_queue.empty() || m_forceExit.load(); });
if (m_forceExit.load())
return false;
popped_value = m_queue.front();
m_queue.pop();
return true;
}
/// <summary> Timed wait and pop an element in the queue. </summary>
/// <param name="popped_value"> [in,out] Element. </param>
/// <param name="milliseconds"> [in] Wait time. </param>
/// <returns> False for timeout or forced exit. </returns>
bool wtpop(dataType &popped_value, long milliseconds = 1000)
{
std::unique_lock<std::mutex> lk(m_mutex);
m_cv.wait_for(lk, std::chrono::milliseconds(milliseconds), [&]() -> bool
{ return !m_queue.empty() || m_forceExit.load(); });
if (m_forceExit.load())
return false;
if (m_queue.empty())
return false;
popped_value = m_queue.front();
m_queue.pop();
return true;
}
/// <summary> Queue size. </summary>
int size()
{
std::unique_lock<std::mutex> lk(m_mutex);
return static_cast<int>(m_queue.size());
}
/// <summary> Free the queue and force stop. </summary>
void clear()
{
m_forceExit.store(true);
std::unique_lock<std::mutex> lk(m_mutex);
while (!m_queue.empty())
{
//delete m_queue.front();
m_queue.pop();
}
lk.unlock();
m_cv.notify_one();
}
/// <summary> Check queue in forced exit state. </summary>
bool isExit() const
{
return m_forceExit.load();
}
};
}
public:
/// <summary> Add a new element in the queue. </summary>
/// <param name="data"> New element. </param>
void push(dataType const& data) {
m_forceExit.store(false);
std::unique_lock<std::mutex> lk(m_mutex);
m_queue.push(data);
lk.unlock();
m_cv.notify_one();
}
/// <summary> Check queue empty. </summary>
/// <returns> True if the queue is empty. </returns>
bool isEmpty() const {
std::unique_lock<std::mutex> lk(m_mutex);
return m_queue.empty();
}
/// <summary> Pop element from queue. </summary>
/// <param name="popped_value"> [in,out] Element. </param>
/// <returns> false if the queue is empty. </returns>
bool pop(dataType& popped_value) {
std::unique_lock<std::mutex> lk(m_mutex);
if (m_queue.empty()) {
return false;
} else {
popped_value = m_queue.front();
m_queue.pop();
return true;
}
}
/// <summary> Wait and pop an element in the queue. </summary>
/// <param name="popped_value"> [in,out] Element. </param>
/// <returns> False for forced exit. </returns>
bool wpop(dataType& popped_value) {
std::unique_lock<std::mutex> lk(m_mutex);
m_cv.wait(lk,
[&]() -> bool { return !m_queue.empty() || m_forceExit.load(); });
if (m_forceExit.load())
return false;
popped_value = m_queue.front();
m_queue.pop();
return true;
}
/// <summary> Timed wait and pop an element in the queue. </summary>
/// <param name="popped_value"> [in,out] Element. </param>
/// <param name="milliseconds"> [in] Wait time. </param>
/// <returns> False for timeout or forced exit. </returns>
bool wtpop(dataType& popped_value, long milliseconds = 1000) {
std::unique_lock<std::mutex> lk(m_mutex);
m_cv.wait_for(lk, std::chrono::milliseconds(milliseconds), [&]() -> bool {
return !m_queue.empty() || m_forceExit.load();
});
if (m_forceExit.load())
return false;
if (m_queue.empty())
return false;
popped_value = m_queue.front();
m_queue.pop();
return true;
}
/// <summary> Queue size. </summary>
int size() {
std::unique_lock<std::mutex> lk(m_mutex);
return static_cast<int>(m_queue.size());
}
/// <summary> Free the queue and force stop. </summary>
void clear() {
m_forceExit.store(true);
std::unique_lock<std::mutex> lk(m_mutex);
while (!m_queue.empty()) {
//delete m_queue.front();
m_queue.pop();
}
lk.unlock();
m_cv.notify_one();
}
/// <summary> Check queue in forced exit state. </summary>
bool isExit() const { return m_forceExit.load(); }
};
} // namespace bell
#endif