modify producer-consumer policy flag

This commit is contained in:
mutouyun 2019-01-26 11:20:04 +08:00
parent bb21429d0d
commit e86d3e10e1
9 changed files with 53 additions and 51 deletions

View File

@ -9,7 +9,7 @@ A high-performance inter-process communication using shared memory on Linux/Wind
* 除STL外无其他依赖
* 无锁lock-free或轻量级spin-lock
* 底层数据结构为循环数组circular array
* `ipc::route`支持单生产多消费,`ipc::channel`支持多生产多消费
* `ipc::route`支持单写多读,`ipc::channel`支持多写多读
## Usage

View File

@ -13,8 +13,7 @@ DESTDIR = ../output
-Wno-attributes \
-Wno-missing-field-initializers \
-Wno-unused-variable \
-Wno-unused-function \
-Wno-class-memaccess
-Wno-unused-function
INCLUDEPATH += \
../test \

View File

@ -6,7 +6,7 @@ set(CMAKE_INCLUDE_CURRENT_DIR ON)
find_package(Qt5 COMPONENTS Core Test REQUIRED)
if(NOT MSVC)
add_compile_options(-Wno-attributes -Wno-missing-field-initializers -Wno-unused-variable -Wno-unused-function -Wno-class-memaccess)
add_compile_options(-Wno-attributes -Wno-missing-field-initializers -Wno-unused-variable -Wno-unused-function)
endif()
include_directories(../../include ../../src ../../test ../../test/capo)

View File

@ -44,10 +44,10 @@ enum class trans { // transmission
// producer-consumer policy flag
template <relat Rp, relat Rc, trans Ts>
struct prod_cons {};
struct wr {};
// implement with multi routes
struct prod_cons_routes {};
struct wr_routes {};
// concept helpers

View File

@ -14,7 +14,7 @@ using handle_t = void*;
using buff_t = buffer;
template <typename Flag>
struct IPC_EXPORT channel_detail {
struct IPC_EXPORT chan_impl {
static handle_t connect (char const * name);
static void disconnect(handle_t h);
@ -26,7 +26,7 @@ struct IPC_EXPORT channel_detail {
};
template <>
struct IPC_EXPORT channel_detail<prod_cons_routes> {
struct IPC_EXPORT chan_impl<wr_routes> {
static handle_t connect (char const * name);
static void disconnect(handle_t h);
@ -38,34 +38,34 @@ struct IPC_EXPORT channel_detail<prod_cons_routes> {
};
template <typename Flag>
class channel_impl {
class chan_wrapper {
private:
using detail_t = channel_detail<Flag>;
using detail_t = chan_impl<Flag>;
handle_t h_ = nullptr;
std::string n_;
public:
channel_impl() = default;
chan_wrapper() = default;
explicit channel_impl(char const * name) {
explicit chan_wrapper(char const * name) {
this->connect(name);
}
channel_impl(channel_impl&& rhs) {
chan_wrapper(chan_wrapper&& rhs) {
swap(rhs);
}
~channel_impl() {
~chan_wrapper() {
disconnect();
}
void swap(channel_impl& rhs) {
void swap(chan_wrapper& rhs) {
std::swap(h_, rhs.h_);
n_.swap(rhs.n_);
}
channel_impl& operator=(channel_impl rhs) {
chan_wrapper& operator=(chan_wrapper rhs) {
swap(rhs);
return *this;
}
@ -82,8 +82,8 @@ public:
return (handle() != nullptr);
}
channel_impl clone() const {
return channel_impl { name() };
chan_wrapper clone() const {
return chan_wrapper { name() };
}
bool connect(char const * name) {
@ -109,7 +109,7 @@ public:
}
static bool wait_for_recv(char const * name, std::size_t r_count) {
return channel_impl(name).wait_for_recv(r_count);
return chan_wrapper(name).wait_for_recv(r_count);
}
bool send(void const * data, std::size_t size) {
@ -129,6 +129,9 @@ public:
}
};
template <typename Flag>
using chan = chan_wrapper<Flag>;
/*
* class route
*
@ -137,19 +140,19 @@ public:
* would receive your sent messages.
*
* A route could only be used in 1 to N
* (one producer/server/sender to multi consumers/clients/receivers)
* (one producer/writer to multi consumers/readers)
*/
using route = channel_impl<ipc::prod_cons<relat::single, relat::multi, trans::broadcast>>;
using route = chan<ipc::wr<relat::single, relat::multi, trans::broadcast>>;
/*
* class channel
*
* You could use multi producers/servers/senders for sending messages to a channel,
* then all the consumers/clients/receivers which are receiving with this channel,
* You could use multi producers/writers for sending messages to a channel,
* then all the consumers/readers which are receiving with this channel,
* would receive your sent messages.
*/
using channel = channel_impl<ipc::prod_cons<relat::multi, relat::multi, trans::broadcast>>;
using channel = chan<ipc::wr<relat::multi, relat::multi, trans::broadcast>>;
} // namespace ipc

View File

@ -88,26 +88,26 @@ struct ch_multi_routes {
namespace ipc {
ipc::handle_t channel_detail<prod_cons_routes>::connect(char const * /*name*/) {
ipc::handle_t chan_impl<wr_routes>::connect(char const * /*name*/) {
return nullptr;
}
void channel_detail<prod_cons_routes>::disconnect(ipc::handle_t /*h*/) {
void chan_impl<wr_routes>::disconnect(ipc::handle_t /*h*/) {
}
std::size_t channel_detail<prod_cons_routes>::recv_count(ipc::handle_t /*h*/) {
std::size_t chan_impl<wr_routes>::recv_count(ipc::handle_t /*h*/) {
return 0;
}
bool channel_detail<prod_cons_routes>::wait_for_recv(ipc::handle_t /*h*/, std::size_t /*r_count*/) {
bool chan_impl<wr_routes>::wait_for_recv(ipc::handle_t /*h*/, std::size_t /*r_count*/) {
return false;
}
bool channel_detail<prod_cons_routes>::send(ipc::handle_t /*h*/, void const * /*data*/, std::size_t /*size*/) {
bool chan_impl<wr_routes>::send(ipc::handle_t /*h*/, void const * /*data*/, std::size_t /*size*/) {
return false;
}
buff_t channel_detail<prod_cons_routes>::recv(ipc::handle_t /*h*/) {
buff_t chan_impl<wr_routes>::recv(ipc::handle_t /*h*/) {
return {};
}

View File

@ -214,39 +214,39 @@ using policy_t = policy::choose<circ::elem_array, Flag>;
namespace ipc {
template <typename Flag>
ipc::handle_t channel_detail<Flag>::connect(char const * name) {
ipc::handle_t chan_impl<Flag>::connect(char const * name) {
return detail_impl<policy_t<Flag>>::connect(name);
}
template <typename Flag>
void channel_detail<Flag>::disconnect(ipc::handle_t h) {
void chan_impl<Flag>::disconnect(ipc::handle_t h) {
detail_impl<policy_t<Flag>>::disconnect(h);
}
template <typename Flag>
std::size_t channel_detail<Flag>::recv_count(ipc::handle_t h) {
std::size_t chan_impl<Flag>::recv_count(ipc::handle_t h) {
return detail_impl<policy_t<Flag>>::recv_count(h);
}
template <typename Flag>
bool channel_detail<Flag>::wait_for_recv(ipc::handle_t h, std::size_t r_count) {
bool chan_impl<Flag>::wait_for_recv(ipc::handle_t h, std::size_t r_count) {
return detail_impl<policy_t<Flag>>::wait_for_recv(h, r_count);
}
template <typename Flag>
bool channel_detail<Flag>::send(ipc::handle_t h, void const * data, std::size_t size) {
bool chan_impl<Flag>::send(ipc::handle_t h, void const * data, std::size_t size) {
return detail_impl<policy_t<Flag>>::send(h, data, size);
}
template <typename Flag>
buff_t channel_detail<Flag>::recv(ipc::handle_t h) {
buff_t chan_impl<Flag>::recv(ipc::handle_t h) {
return detail_impl<policy_t<Flag>>::recv(h);
}
template struct channel_detail<ipc::prod_cons<relat::single, relat::single, trans::unicast >>;
template struct channel_detail<ipc::prod_cons<relat::single, relat::multi , trans::unicast >>;
template struct channel_detail<ipc::prod_cons<relat::multi , relat::multi , trans::unicast >>;
template struct channel_detail<ipc::prod_cons<relat::single, relat::multi , trans::broadcast>>;
template struct channel_detail<ipc::prod_cons<relat::multi , relat::multi , trans::broadcast>>;
template struct chan_impl<ipc::wr<relat::single, relat::single, trans::unicast >>;
template struct chan_impl<ipc::wr<relat::single, relat::multi , trans::unicast >>;
template struct chan_impl<ipc::wr<relat::multi , relat::multi , trans::unicast >>;
template struct chan_impl<ipc::wr<relat::single, relat::multi , trans::broadcast>>;
template struct chan_impl<ipc::wr<relat::multi , relat::multi , trans::broadcast>>;
} // namespace ipc

View File

@ -19,7 +19,7 @@ template <typename Flag>
struct prod_cons_impl;
template <>
struct prod_cons_impl<prod_cons<relat::single, relat::single, trans::unicast>> {
struct prod_cons_impl<wr<relat::single, relat::single, trans::unicast>> {
std::atomic<circ::u2_t> rd_; // read index
std::atomic<circ::u2_t> wt_; // write index
@ -63,8 +63,8 @@ struct prod_cons_impl<prod_cons<relat::single, relat::single, trans::unicast>> {
};
template <>
struct prod_cons_impl<prod_cons<relat::single, relat::multi , trans::unicast>>
: prod_cons_impl<prod_cons<relat::single, relat::single, trans::unicast>> {
struct prod_cons_impl<wr<relat::single, relat::multi , trans::unicast>>
: prod_cons_impl<wr<relat::single, relat::single, trans::unicast>> {
template <typename E, typename F, typename EB>
bool pop(E* /*elems*/, circ::u2_t& /*cur*/, F&& f, EB* elem_start) {
@ -86,8 +86,8 @@ struct prod_cons_impl<prod_cons<relat::single, relat::multi , trans::unicast>>
};
template <>
struct prod_cons_impl<prod_cons<relat::multi , relat::multi, trans::unicast>>
: prod_cons_impl<prod_cons<relat::single, relat::multi, trans::unicast>> {
struct prod_cons_impl<wr<relat::multi , relat::multi, trans::unicast>>
: prod_cons_impl<wr<relat::single, relat::multi, trans::unicast>> {
std::atomic<circ::u2_t> ct_; // commit index
@ -118,7 +118,7 @@ struct prod_cons_impl<prod_cons<relat::multi , relat::multi, trans::unicast>>
};
template <>
struct prod_cons_impl<prod_cons<relat::single, relat::multi, trans::broadcast>> {
struct prod_cons_impl<wr<relat::single, relat::multi, trans::broadcast>> {
std::atomic<circ::u2_t> wt_; // write index
#if __cplusplus >= 201703L
@ -180,8 +180,8 @@ struct prod_cons_impl<prod_cons<relat::single, relat::multi, trans::broadcast>>
};
template <>
struct prod_cons_impl<prod_cons<relat::multi , relat::multi, trans::broadcast>>
: prod_cons_impl<prod_cons<relat::single, relat::multi, trans::broadcast>> {
struct prod_cons_impl<wr<relat::multi , relat::multi, trans::broadcast>>
: prod_cons_impl<wr<relat::single, relat::multi, trans::broadcast>> {
std::atomic<circ::u2_t> ct_; // commit index

View File

@ -21,7 +21,7 @@ struct msg_t {
};
template <ipc::relat Rp, ipc::relat Rc, ipc::trans Ts>
using pc_t = ipc::prod_cons_impl<ipc::prod_cons<Rp, Rc, Ts>>;
using pc_t = ipc::prod_cons_impl<ipc::wr<Rp, Rc, Ts>>;
template <std::size_t DataSize, typename Policy>
struct ea_t : public ipc::circ::elem_array<Policy, DataSize> {
@ -372,7 +372,7 @@ void Unit::test_prod_cons_performance() {
void Unit::test_queue() {
using queue_t = ipc::queue<msg_t, ipc::policy::choose<
ipc::circ::elem_array,
ipc::prod_cons<ipc::relat::single, ipc::relat::multi, ipc::trans::broadcast>
ipc::wr<ipc::relat::single, ipc::relat::multi, ipc::trans::broadcast>
>>;
queue_t queue;