use shm::id_t instead of shm::handle in conn_info_head

This commit is contained in:
zhangyi 2019-06-18 11:53:43 +08:00
parent 7795156656
commit 30fa347f56
6 changed files with 52 additions and 23 deletions

View File

@ -17,6 +17,7 @@ enum : unsigned {
IPC_EXPORT id_t acquire(char const * name, std::size_t size, unsigned mode = create | open); IPC_EXPORT id_t acquire(char const * name, std::size_t size, unsigned mode = create | open);
IPC_EXPORT void * get_mem(id_t id, std::size_t * size); IPC_EXPORT void * get_mem(id_t id, std::size_t * size);
IPC_EXPORT void release(id_t id); IPC_EXPORT void release(id_t id);
IPC_EXPORT void remove (id_t id);
IPC_EXPORT void remove (char const * name); IPC_EXPORT void remove (char const * name);
class IPC_EXPORT handle { class IPC_EXPORT handle {

View File

@ -12,7 +12,9 @@
namespace ipc { namespace ipc {
namespace circ { namespace circ {
template <typename Policy, std::size_t DataSize, std::size_t AlignSize> template <typename Policy,
std::size_t DataSize,
std::size_t AlignSize = (ipc::detail::min)(DataSize, alignof(std::max_align_t))>
class elem_array : public ipc::circ::conn_head { class elem_array : public ipc::circ::conn_head {
public: public:
using base_t = ipc::circ::conn_head; using base_t = ipc::circ::conn_head;
@ -30,7 +32,7 @@ public:
private: private:
policy_t head_; policy_t head_;
elem_t block_[elem_max]; elem_t block_[elem_max] {};
public: public:
cursor_t cursor() const noexcept { cursor_t cursor() const noexcept {

View File

@ -112,7 +112,7 @@ struct conn_info_head {
struct simple_push { struct simple_push {
template <std::size_t, std::size_t> template <std::size_t, std::size_t>
using elem_t = shm::handle; using elem_t = shm::id_t;
circ::u2_t wt_; // write index circ::u2_t wt_; // write index
@ -128,7 +128,7 @@ struct conn_info_head {
} }
}; };
circ::elem_array<simple_push, sizeof(shm::handle), 0> msg_datas_; circ::elem_array<simple_push, sizeof(shm::id_t)> msg_datas_;
conn_info_head(char const * name) conn_info_head(char const * name)
: cc_id_ ((acc() == nullptr) ? 0 : acc()->fetch_add(1, std::memory_order_relaxed)) : cc_id_ ((acc() == nullptr) ? 0 : acc()->fetch_add(1, std::memory_order_relaxed))
@ -137,20 +137,24 @@ struct conn_info_head {
, rd_waiter_((std::string { "__RD_CONN__" } + name).c_str()) { , rd_waiter_((std::string { "__RD_CONN__" } + name).c_str()) {
} }
static shm::handle apply_storage(msg_id_t msg_id, std::size_t size) { static shm::id_t apply_storage(msg_id_t msg_id, std::size_t size) {
return { ("__ST_CONN__" + std::to_string(msg_id)).c_str(), size, shm::create }; return shm::acquire(("__ST_CONN__" + std::to_string(msg_id)).c_str(), size, shm::create);
} }
static shm::handle apply_storage(msg_id_t msg_id) { static shm::id_t apply_storage(msg_id_t msg_id) {
return { ("__ST_CONN__" + std::to_string(msg_id)).c_str(), 0, shm::open }; return shm::acquire(("__ST_CONN__" + std::to_string(msg_id)).c_str(), 0, shm::open);
} }
void store(shm::handle && dat) { void store(shm::id_t dat) {
msg_datas_.push([&dat](shm::handle * p) { p->swap(dat); }); msg_datas_.push([dat](shm::id_t * id) {
(*id) = dat;
});
} }
void clear_store() { void clear_store() {
msg_datas_.push([](shm::handle * p) { p->release(); }); msg_datas_.push([](shm::id_t * id) {
if (*id != nullptr) shm::remove(*id);
});
} }
}; };
@ -271,10 +275,10 @@ static bool send(F&& gen_push, ipc::handle_t h, void const * data, std::size_t s
auto try_push = std::forward<F>(gen_push)(info_of(h), que, msg_id); auto try_push = std::forward<F>(gen_push)(info_of(h), que, msg_id);
if (size > small_msg_limit) { if (size > small_msg_limit) {
auto dat = info_of(h)->apply_storage(msg_id, size); auto dat = info_of(h)->apply_storage(msg_id, size);
void * buf = dat.get(); void * buf = shm::get_mem(dat, nullptr);
if (buf != nullptr) { if (buf != nullptr) {
std::memcpy(buf, data, size); std::memcpy(buf, data, size);
info_of(h)->store(std::move(dat)); info_of(h)->store(dat);
return try_push(static_cast<int>(size) - static_cast<int>(data_length), nullptr, 0); return try_push(static_cast<int>(size) - static_cast<int>(data_length), nullptr, 0);
} }
// try using message fragment // try using message fragment
@ -362,16 +366,15 @@ static buff_t recv(ipc::handle_t h, std::size_t tm) {
} }
if (msg.head_.storage_) { if (msg.head_.storage_) {
auto dat = info_of(h)->apply_storage(msg.head_.id_); auto dat = info_of(h)->apply_storage(msg.head_.id_);
void * buf = dat.get(); std::size_t dat_sz = 0;
if (buf != nullptr && remain <= dat.size()) { void * buf = shm::get_mem(dat, &dat_sz);
auto id = dat.detach(); if (buf != nullptr && remain <= dat_sz) {
return buff_t { buf, remain, [id](void *, std::size_t) { return buff_t { buf, remain, [dat](void *, std::size_t) {
shm::handle dat; shm::release(dat);
dat.attach(id);
}, buff_t::use::functor }; }, buff_t::use::functor };
} }
else ipc::log("fail: shm::handle for big message. msg_id: %zd, size: %zd, shm.size: %zd\n", else ipc::log("fail: shm::handle for big message. msg_id: %zd, size: %zd, shm.size: %zd\n",
msg.head_.id_, remain, dat.size()); msg.head_.id_, remain, dat_sz);
} }
// gc // gc
if (rc.size() > 1024) { if (rc.size() > 1024) {

View File

@ -137,12 +137,27 @@ void release(id_t id) {
} }
else if (acc_of(ii->mem_, ii->size_).fetch_sub(1, std::memory_order_acquire) == 1) { else if (acc_of(ii->mem_, ii->size_).fetch_sub(1, std::memory_order_acquire) == 1) {
::munmap(ii->mem_, ii->size_); ::munmap(ii->mem_, ii->size_);
if (!ii->name_.empty()) {
::shm_unlink(ii->name_.c_str()); ::shm_unlink(ii->name_.c_str());
} }
}
else ::munmap(ii->mem_, ii->size_); else ::munmap(ii->mem_, ii->size_);
mem::free(ii); mem::free(ii);
} }
void remove(id_t id) {
if (id == nullptr) {
ipc::error("fail remove: invalid id (null)\n");
return;
}
auto ii = static_cast<id_info_t*>(id);
auto name = std::move(ii->name_);
release(id);
if (!name.empty()) {
::shm_unlink(name.c_str());
}
}
void remove(char const * name) { void remove(char const * name) {
if (name == nullptr || name[0] == '\0') { if (name == nullptr || name[0] == '\0') {
ipc::error("fail remove: name is empty\n"); ipc::error("fail remove: name is empty\n");

View File

@ -103,6 +103,14 @@ void release(id_t id) {
mem::free(ii); mem::free(ii);
} }
void remove(id_t id) {
if (id == nullptr) {
ipc::error("fail release: invalid id (null)\n");
return;
}
release(id);
}
void remove(char const * name) { void remove(char const * name) {
if (name == nullptr || name[0] == '\0') { if (name == nullptr || name[0] == '\0') {
ipc::error("fail remove: name is empty\n"); ipc::error("fail remove: name is empty\n");

View File

@ -238,7 +238,7 @@ private slots:
void test_prod_cons_1v3(); void test_prod_cons_1v3();
void test_prod_cons_performance(); void test_prod_cons_performance();
void test_queue(); void test_queue();
} unit__; } /*unit__*/;
#include "test_circ.moc" #include "test_circ.moc"