summaryrefslogtreecommitdiff
path: root/src/utils/sem_queue.h
blob: 6987d8889af744c6406bf73c8ca96e9e5a06d82e (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
#pragma once

#include <mutex>
#include <queue>
#include <semaphore>

template<typename T, size_t S>
class sem_queue
{
public:
    inline void enqueue(const T &value)
    {
        m_free.acquire();
        std::lock_guard l{m_mtx};
        m_queue.push(value);
        m_used.release();
    }

    inline T dequeue()
    {
        m_used.acquire();
        std::lock_guard l{m_mtx};
        const auto result = m_queue.front();
        m_queue.pop();
        m_free.release();

        return result;
    }

private:
    std::queue<T> m_queue;
    std::mutex m_mtx;
    std::counting_semaphore<S> m_free{S};
    std::counting_semaphore<S> m_used{0};
};