From a35b43163cddd6ed1c054cd673773f517f8d9790 Mon Sep 17 00:00:00 2001 From: zhangyi Date: Wed, 27 Mar 2019 16:58:46 +0800 Subject: [PATCH] support removing waiter-objects forcibly --- include/shm.h | 1 + include/waiter.h | 6 ++++++ src/platform/shm_linux.cpp | 12 ++++++++++++ src/platform/shm_win.cpp | 3 +++ src/platform/waiter_win.h | 8 ++++++++ src/platform/waiter_wrapper.h | 24 +++++++++++++++++++++++- src/waiter_template.inc | 4 ++++ 7 files changed, 57 insertions(+), 1 deletion(-) diff --git a/include/shm.h b/include/shm.h index 163d3bd..b48ed8c 100644 --- a/include/shm.h +++ b/include/shm.h @@ -12,6 +12,7 @@ using id_t = void*; IPC_EXPORT id_t acquire(char const * name, std::size_t size); IPC_EXPORT void * to_mem (id_t id); IPC_EXPORT void release(id_t id, void * mem, std::size_t size); +IPC_EXPORT void remove (char const * name); class IPC_EXPORT handle { public: diff --git a/include/waiter.h b/include/waiter.h index 91bea3c..74dceef 100644 --- a/include/waiter.h +++ b/include/waiter.h @@ -14,6 +14,8 @@ public: ~mutex(); + static void remove(char const * name); + void swap(mutex& rhs); mutex& operator=(mutex rhs); @@ -41,6 +43,8 @@ public: ~semaphore(); + static void remove(char const * name); + void swap(semaphore& rhs); semaphore& operator=(semaphore rhs); @@ -66,6 +70,8 @@ public: ~condition(); + static void remove(char const * name); + void swap(condition& rhs); condition& operator=(condition rhs); diff --git a/src/platform/shm_linux.cpp b/src/platform/shm_linux.cpp index a291da1..c568c38 100644 --- a/src/platform/shm_linux.cpp +++ b/src/platform/shm_linux.cpp @@ -98,5 +98,17 @@ void release(id_t id, void * mem, std::size_t size) { else ::munmap(mem, size); } +void remove(char const * name) { + if (name == nullptr || name[0] == '\0') { + return; + } + std::string op_name = std::string{"__IPC_SHM__"} + name; + if (op_name.size() >= ipc::name_length) { + ipc::error("name is too long!: [%d]%s\n", static_cast(op_name.size()), op_name.c_str()); + return; + } + ::shm_unlink(op_name.c_str()); +} + } // namespace shm } // namespace ipc diff --git a/src/platform/shm_win.cpp b/src/platform/shm_win.cpp index 24945e5..e3398e4 100644 --- a/src/platform/shm_win.cpp +++ b/src/platform/shm_win.cpp @@ -46,5 +46,8 @@ void release(id_t id, void * mem, std::size_t /*size*/) { ::CloseHandle(static_cast(id)); } +void remove(char const * /*name*/) { +} + } // namespace shm } // namespace ipc diff --git a/src/platform/waiter_win.h b/src/platform/waiter_win.h index db0daf6..21daf0a 100644 --- a/src/platform/waiter_win.h +++ b/src/platform/waiter_win.h @@ -20,6 +20,8 @@ class semaphore { HANDLE h_ = NULL; public: + static void remove(char const * /*name*/) {} + bool open(std::string && name, long count = 0, long limit = LONG_MAX) { h_ = ::CreateSemaphore(NULL, count, limit, ipc::detail::to_tchar(std::move(name)).c_str()); if (h_ == NULL) { @@ -83,6 +85,12 @@ public: return !(c1 == c2); } + static void remove(char const * name) { + semaphore::remove(std::string{ "__COND_HAN__" } + name); + semaphore::remove(std::string{ "__COND_SEM__" } + name); + mutex ::remove(std::string{ "__COND_MTX__" } + name); + } + bool open(std::string const & name, std::atomic * waiting, long * counter) { if (lock_ .open("__COND_MTX__" + name) && sema_ .open("__COND_SEM__" + name) && diff --git a/src/platform/waiter_wrapper.h b/src/platform/waiter_wrapper.h index e81676c..06a76a9 100644 --- a/src/platform/waiter_wrapper.h +++ b/src/platform/waiter_wrapper.h @@ -24,6 +24,12 @@ class condition_impl : public ipc::detail::condition { ipc::shm::handle wait_h_, cnt_h_; public: + static void remove(char const * name) { + ipc::detail::condition::remove(name); + ipc::shm::remove((name + "__COND_CNT__" ).c_str()); + ipc::shm::remove((name + "__COND_WAIT__").c_str()); + } + bool open(std::string const & name) { if (wait_h_.acquire((name + "__COND_WAIT__").c_str(), sizeof(std::atomic)) && cnt_h_ .acquire((name + "__COND_CNT__" ).c_str(), sizeof(long))) { @@ -36,8 +42,8 @@ public: void close() { ipc::detail::condition::close(); - wait_h_.release(); cnt_h_ .release(); + wait_h_.release(); } bool wait(mutex_impl& mtx, std::size_t tm = invalid_value) { @@ -65,6 +71,17 @@ class object_impl { }; public: + static void remove(char const * name) { + { + ipc::shm::handle h { name, sizeof(info_t) }; + if (h.valid()) { + auto info = static_cast(h.get()); + info->object_.close(); + } + } + ipc::shm::remove(name); + } + T& object() { return static_cast(h_.get())->object_; } @@ -118,6 +135,11 @@ class semaphore_impl { } public: + static void remove(char const * name) { + sem_helper::destroy((std::string{ "__SEMAPHORE_IMPL_SEM__" } + name).c_str()); + ipc::shm::remove ((std::string{ "__SEMAPHORE_IMPL_CNT__" } + name).c_str()); + } + bool open(char const * name, long count) { name_ = name; if (!opened_.acquire(("__SEMAPHORE_IMPL_CNT__" + name_).c_str(), sizeof(std::atomic))) { diff --git a/src/waiter_template.inc b/src/waiter_template.inc index 70b1ef7..976b3d4 100644 --- a/src/waiter_template.inc +++ b/src/waiter_template.inc @@ -11,6 +11,10 @@ public: ipc::detail::IPC_OBJECT_TYPE_I_ h_; }; +void IPC_OBJECT_TYPE_::remove(char const * name) { + detail::IPC_OBJECT_TYPE_I_::remove(name); +} + IPC_OBJECT_TYPE_::IPC_OBJECT_TYPE_() : p_(p_->make()) { }