mirror of
https://github.com/mutouyun/cpp-ipc.git
synced 2025-12-07 09:16:46 +08:00
80 lines
2.0 KiB
C++
80 lines
2.0 KiB
C++
/**
|
|
* \file libconcur/queue.h
|
|
* \author mutouyun (orz@orzz.org)
|
|
* \brief Define concurrent queue.
|
|
* \date 2022-11-19
|
|
*/
|
|
#pragma once
|
|
|
|
#include <cstddef>
|
|
|
|
#include "libimp/construct.h"
|
|
#include "libimp/detect_plat.h"
|
|
|
|
#include "libpmr/allocator.h"
|
|
#include "libpmr/memory_resource.h"
|
|
|
|
#include "libconcur/def.h"
|
|
#include "libconcur/concurrent.h"
|
|
|
|
LIBCONCUR_NAMESPACE_BEG_
|
|
|
|
template <typename T, typename PRelationT, typename CRelationT>
|
|
class queue {
|
|
public:
|
|
using producer_relation_t = PRelationT;
|
|
using consumer_relation_t = CRelationT;
|
|
using model_type = prod_cons<trans::unicast, producer_relation_t, consumer_relation_t>;
|
|
using value_type = T;
|
|
|
|
private:
|
|
struct data {
|
|
model_type model_;
|
|
typename concur::traits<model_type>::header header_;
|
|
element<value_type> elements_start_;
|
|
|
|
template <typename U>
|
|
data(U &&model) noexcept
|
|
: header_(std::forward<U>(model)) {}
|
|
|
|
/// \brief element<value_type> elements[0];
|
|
element<value_type> *elements() noexcept {
|
|
return &elements_start_;
|
|
}
|
|
};
|
|
|
|
data *init(index_t circ_size) noexcept {
|
|
if (!data_allocator_) {
|
|
return nullptr;
|
|
}
|
|
LIBIMP_TRY {
|
|
auto data_ptr = data_allocator_.allocate(sizeof(data) + (circ_size - 1) * sizeof(element<value_type>));
|
|
if (data_ptr == nullptr) {
|
|
return nullptr;
|
|
}
|
|
return ::LIBIMP::construct<data>(data_ptr, circ_size);
|
|
} LIBIMP_CATCH(...) {
|
|
return nullptr;
|
|
}
|
|
}
|
|
|
|
::LIBPMR::allocator data_allocator_;
|
|
data *data_;
|
|
typename concur::traits<model_type>::context context_;
|
|
|
|
public:
|
|
queue() = default;
|
|
queue(queue const &) = delete;
|
|
queue(queue &&) = delete;
|
|
queue &operator=(queue const &) = delete;
|
|
queue &operator=(queue &&) = delete;
|
|
|
|
template <typename MR, ::LIBPMR::verify_memory_resource<T> = true>
|
|
explicit queue(index_t circ_size = default_circle_buffer_size,
|
|
MR *memory_resource = ::LIBPMR::new_delete_resource::get()) noexcept
|
|
: data_allocator_(memory_resource)
|
|
, data_(init(circ_size)) {}
|
|
};
|
|
|
|
LIBCONCUR_NAMESPACE_END_
|