Skip to content

Instantly share code, notes, and snippets.

@jonas-s-s-s
Created September 22, 2024 01:33
Show Gist options
  • Save jonas-s-s-s/3c31e8b3c20b0b091485aa8f5565be80 to your computer and use it in GitHub Desktop.
Save jonas-s-s-s/3c31e8b3c20b0b091485aa8f5565be80 to your computer and use it in GitHub Desktop.
Thread safe queue using eventfd
//
// Created by J. on 12.11.2023.
//
#pragma once
#include <mutex>
#include <queue>
#include <sys/eventfd.h>
template <typename T> class EventfdQueue {
private:
std::queue<T> data;
std::mutex dataMutex;
const int evfd = eventfd(0, 0);
public:
EventfdQueue()
{
if (evfd == -1)
throw std::runtime_error("EventfdQueue(): ERROR - Eventfd creation failed.");
}
void push(T&& item)
{
static_assert(std::is_rvalue_reference_v<T&&>);
std::scoped_lock lock{dataMutex};
data.push(std::move(item));
// An event is created - signals write into queue - can be captured by epoll
eventfd_write(evfd, 1);
}
void push(T& item)
{
static_assert(std::is_lvalue_reference_v<T&>);
std::scoped_lock lock{dataMutex};
data.push(item);
// An event is created - signals write into queue - can be captured by epoll
eventfd_write(evfd, 1);
}
T pop()
{
if constexpr (std::is_rvalue_reference_v<T&&>) {
std::scoped_lock lock{dataMutex};
T item = std::move(data.front());
data.pop();
return std::move(item);
} else {
std::scoped_lock lock{dataMutex};
T item = data.front();
data.pop();
return item;
}
}
bool isEmpty()
{
std::scoped_lock lock{dataMutex};
return data.empty();
}
/**
* Thread safe by default.
* @return Returns const int representing this queue's eventfd
*/
int getEvfd() const
{
return evfd;
}
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment