mirror of
https://github.com/mutouyun/cpp-ipc.git
synced 2025-12-07 01:06:45 +08:00
115 lines
2.4 KiB
C++
115 lines
2.4 KiB
C++
#include <array>
|
|
#include <string>
|
|
|
|
#include "ipc.h"
|
|
#include "shm.h"
|
|
#include "rw_lock.h"
|
|
#include "id_pool.h"
|
|
|
|
#include "platform/detail.h"
|
|
|
|
namespace {
|
|
|
|
using namespace ipc;
|
|
|
|
struct ch_info_t {
|
|
rw_lock lc_;
|
|
id_pool ch_acc_; // only support 255 channels with one name
|
|
};
|
|
|
|
struct ch_multi_routes {
|
|
shm::handle h_;
|
|
route r_;
|
|
|
|
std::size_t id_;
|
|
bool marked_ = false;
|
|
|
|
std::array<route, id_pool::max_count> rts_;
|
|
|
|
ch_info_t& info() {
|
|
return *static_cast<ch_info_t*>(h_.get());
|
|
}
|
|
|
|
auto& acc() {
|
|
return info().ch_acc_;
|
|
}
|
|
|
|
void mark_id() {
|
|
if (marked_) return;
|
|
marked_ = true;
|
|
IPC_UNUSED_ auto guard = ipc::detail::unique_lock(info().lc_);
|
|
acc().mark_acquired(id_);
|
|
}
|
|
|
|
auto& sender() {
|
|
mark_id();
|
|
return r_;
|
|
}
|
|
|
|
bool valid() const {
|
|
return h_.valid() && r_.valid();
|
|
}
|
|
|
|
bool connect(char const * name) {
|
|
if (name == nullptr || name[0] == '\0') {
|
|
return false;
|
|
}
|
|
disconnect();
|
|
if (!h_.acquire((std::string { name } + "_").c_str(), sizeof(ch_info_t))) {
|
|
return false;
|
|
}
|
|
{
|
|
IPC_UNUSED_ auto guard = ipc::detail::unique_lock(info().lc_);
|
|
if (acc().invalid()) acc().init();
|
|
id_ = acc().acquire();
|
|
}
|
|
if (id_ == invalid_value) {
|
|
return false;
|
|
}
|
|
r_.connect((name + std::to_string(id_)).c_str());
|
|
return valid();
|
|
}
|
|
|
|
void disconnect() {
|
|
if (!valid()) return;
|
|
{
|
|
IPC_UNUSED_ auto guard = ipc::detail::unique_lock(info().lc_);
|
|
acc().release(id_);
|
|
}
|
|
for (auto& rt : rts_) {
|
|
rt.disconnect();
|
|
}
|
|
r_.disconnect();
|
|
h_.release();
|
|
}
|
|
};
|
|
|
|
} // internal-linkage
|
|
|
|
namespace ipc {
|
|
|
|
ipc::handle_t chan_impl<wr_routes>::connect(char const * /*name*/) {
|
|
return nullptr;
|
|
}
|
|
|
|
void chan_impl<wr_routes>::disconnect(ipc::handle_t /*h*/) {
|
|
}
|
|
|
|
std::size_t chan_impl<wr_routes>::recv_count(ipc::handle_t /*h*/) {
|
|
return 0;
|
|
}
|
|
|
|
bool chan_impl<wr_routes>::wait_for_recv(ipc::handle_t /*h*/, std::size_t /*r_count*/) {
|
|
return false;
|
|
}
|
|
|
|
bool chan_impl<wr_routes>::send(ipc::handle_t /*h*/, void const * /*data*/, std::size_t /*size*/) {
|
|
return false;
|
|
}
|
|
|
|
buff_t chan_impl<wr_routes>::recv(ipc::handle_t /*h*/) {
|
|
return {};
|
|
}
|
|
|
|
} // namespace ipc
|