From 30fa347f561c0b14f56f7042e192c17fd567c2e6 Mon Sep 17 00:00:00 2001 From: zhangyi Date: Tue, 18 Jun 2019 11:53:43 +0800 Subject: [PATCH] use shm::id_t instead of shm::handle in conn_info_head --- include/shm.h | 1 + src/circ/elem_array.h | 6 ++++-- src/ipc.cpp | 41 ++++++++++++++++++++------------------ src/platform/shm_linux.cpp | 17 +++++++++++++++- src/platform/shm_win.cpp | 8 ++++++++ test/test_circ.cpp | 2 +- 6 files changed, 52 insertions(+), 23 deletions(-) diff --git a/include/shm.h b/include/shm.h index a20731e..8a8ae7c 100644 --- a/include/shm.h +++ b/include/shm.h @@ -17,6 +17,7 @@ enum : unsigned { 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 release(id_t id); +IPC_EXPORT void remove (id_t id); IPC_EXPORT void remove (char const * name); class IPC_EXPORT handle { diff --git a/src/circ/elem_array.h b/src/circ/elem_array.h index 8ed8116..27ace56 100644 --- a/src/circ/elem_array.h +++ b/src/circ/elem_array.h @@ -12,7 +12,9 @@ namespace ipc { namespace circ { -template +template class elem_array : public ipc::circ::conn_head { public: using base_t = ipc::circ::conn_head; @@ -30,7 +32,7 @@ public: private: policy_t head_; - elem_t block_[elem_max]; + elem_t block_[elem_max] {}; public: cursor_t cursor() const noexcept { diff --git a/src/ipc.cpp b/src/ipc.cpp index c9d02ef..bb58e6a 100644 --- a/src/ipc.cpp +++ b/src/ipc.cpp @@ -112,7 +112,7 @@ struct conn_info_head { struct simple_push { template - using elem_t = shm::handle; + using elem_t = shm::id_t; circ::u2_t wt_; // write index @@ -128,7 +128,7 @@ struct conn_info_head { } }; - circ::elem_array msg_datas_; + circ::elem_array msg_datas_; conn_info_head(char const * name) : 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()) { } - static shm::handle apply_storage(msg_id_t msg_id, std::size_t size) { - return { ("__ST_CONN__" + std::to_string(msg_id)).c_str(), size, shm::create }; + static shm::id_t apply_storage(msg_id_t msg_id, std::size_t size) { + 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) { - return { ("__ST_CONN__" + std::to_string(msg_id)).c_str(), 0, shm::open }; + static shm::id_t apply_storage(msg_id_t msg_id) { + return shm::acquire(("__ST_CONN__" + std::to_string(msg_id)).c_str(), 0, shm::open); } - void store(shm::handle && dat) { - msg_datas_.push([&dat](shm::handle * p) { p->swap(dat); }); + void store(shm::id_t dat) { + msg_datas_.push([dat](shm::id_t * id) { + (*id) = dat; + }); } 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(gen_push)(info_of(h), que, msg_id); if (size > small_msg_limit) { auto dat = info_of(h)->apply_storage(msg_id, size); - void * buf = dat.get(); + void * buf = shm::get_mem(dat, nullptr); if (buf != nullptr) { std::memcpy(buf, data, size); - info_of(h)->store(std::move(dat)); + info_of(h)->store(dat); return try_push(static_cast(size) - static_cast(data_length), nullptr, 0); } // try using message fragment @@ -361,17 +365,16 @@ static buff_t recv(ipc::handle_t h, std::size_t tm) { return make_cache(msg.data_, remain); } if (msg.head_.storage_) { - auto dat = info_of(h)->apply_storage(msg.head_.id_); - void * buf = dat.get(); - if (buf != nullptr && remain <= dat.size()) { - auto id = dat.detach(); - return buff_t { buf, remain, [id](void *, std::size_t) { - shm::handle dat; - dat.attach(id); + auto dat = info_of(h)->apply_storage(msg.head_.id_); + std::size_t dat_sz = 0; + void * buf = shm::get_mem(dat, &dat_sz); + if (buf != nullptr && remain <= dat_sz) { + return buff_t { buf, remain, [dat](void *, std::size_t) { + shm::release(dat); }, buff_t::use::functor }; } 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 if (rc.size() > 1024) { diff --git a/src/platform/shm_linux.cpp b/src/platform/shm_linux.cpp index 706a37d..84fbc51 100644 --- a/src/platform/shm_linux.cpp +++ b/src/platform/shm_linux.cpp @@ -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) { ::munmap(ii->mem_, ii->size_); - ::shm_unlink(ii->name_.c_str()); + if (!ii->name_.empty()) { + ::shm_unlink(ii->name_.c_str()); + } } else ::munmap(ii->mem_, ii->size_); 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); + auto name = std::move(ii->name_); + release(id); + if (!name.empty()) { + ::shm_unlink(name.c_str()); + } +} + void remove(char const * name) { if (name == nullptr || name[0] == '\0') { ipc::error("fail remove: name is empty\n"); diff --git a/src/platform/shm_win.cpp b/src/platform/shm_win.cpp index 3e1408c..52e0cd3 100644 --- a/src/platform/shm_win.cpp +++ b/src/platform/shm_win.cpp @@ -103,6 +103,14 @@ void release(id_t id) { 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) { if (name == nullptr || name[0] == '\0') { ipc::error("fail remove: name is empty\n"); diff --git a/test/test_circ.cpp b/test/test_circ.cpp index 2e10e50..bdf6b7d 100644 --- a/test/test_circ.cpp +++ b/test/test_circ.cpp @@ -238,7 +238,7 @@ private slots: void test_prod_cons_1v3(); void test_prod_cons_performance(); void test_queue(); -} unit__; +} /*unit__*/; #include "test_circ.moc"