support removing waiter-objects forcibly

This commit is contained in:
zhangyi 2019-03-27 16:58:46 +08:00
parent f6268ce62d
commit a35b43163c
7 changed files with 57 additions and 1 deletions

View File

@ -12,6 +12,7 @@ using id_t = void*;
IPC_EXPORT id_t acquire(char const * name, std::size_t size); IPC_EXPORT id_t acquire(char const * name, std::size_t size);
IPC_EXPORT void * to_mem (id_t id); IPC_EXPORT void * to_mem (id_t id);
IPC_EXPORT void release(id_t id, void * mem, std::size_t size); IPC_EXPORT void release(id_t id, void * mem, std::size_t size);
IPC_EXPORT void remove (char const * name);
class IPC_EXPORT handle { class IPC_EXPORT handle {
public: public:

View File

@ -14,6 +14,8 @@ public:
~mutex(); ~mutex();
static void remove(char const * name);
void swap(mutex& rhs); void swap(mutex& rhs);
mutex& operator=(mutex rhs); mutex& operator=(mutex rhs);
@ -41,6 +43,8 @@ public:
~semaphore(); ~semaphore();
static void remove(char const * name);
void swap(semaphore& rhs); void swap(semaphore& rhs);
semaphore& operator=(semaphore rhs); semaphore& operator=(semaphore rhs);
@ -66,6 +70,8 @@ public:
~condition(); ~condition();
static void remove(char const * name);
void swap(condition& rhs); void swap(condition& rhs);
condition& operator=(condition rhs); condition& operator=(condition rhs);

View File

@ -98,5 +98,17 @@ void release(id_t id, void * mem, std::size_t size) {
else ::munmap(mem, 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<int>(op_name.size()), op_name.c_str());
return;
}
::shm_unlink(op_name.c_str());
}
} // namespace shm } // namespace shm
} // namespace ipc } // namespace ipc

View File

@ -46,5 +46,8 @@ void release(id_t id, void * mem, std::size_t /*size*/) {
::CloseHandle(static_cast<HANDLE>(id)); ::CloseHandle(static_cast<HANDLE>(id));
} }
void remove(char const * /*name*/) {
}
} // namespace shm } // namespace shm
} // namespace ipc } // namespace ipc

View File

@ -20,6 +20,8 @@ class semaphore {
HANDLE h_ = NULL; HANDLE h_ = NULL;
public: public:
static void remove(char const * /*name*/) {}
bool open(std::string && name, long count = 0, long limit = LONG_MAX) { 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()); h_ = ::CreateSemaphore(NULL, count, limit, ipc::detail::to_tchar(std::move(name)).c_str());
if (h_ == NULL) { if (h_ == NULL) {
@ -83,6 +85,12 @@ public:
return !(c1 == c2); 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<unsigned> * waiting, long * counter) { bool open(std::string const & name, std::atomic<unsigned> * waiting, long * counter) {
if (lock_ .open("__COND_MTX__" + name) && if (lock_ .open("__COND_MTX__" + name) &&
sema_ .open("__COND_SEM__" + name) && sema_ .open("__COND_SEM__" + name) &&

View File

@ -24,6 +24,12 @@ class condition_impl : public ipc::detail::condition {
ipc::shm::handle wait_h_, cnt_h_; ipc::shm::handle wait_h_, cnt_h_;
public: 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) { bool open(std::string const & name) {
if (wait_h_.acquire((name + "__COND_WAIT__").c_str(), sizeof(std::atomic<unsigned>)) && if (wait_h_.acquire((name + "__COND_WAIT__").c_str(), sizeof(std::atomic<unsigned>)) &&
cnt_h_ .acquire((name + "__COND_CNT__" ).c_str(), sizeof(long))) { cnt_h_ .acquire((name + "__COND_CNT__" ).c_str(), sizeof(long))) {
@ -36,8 +42,8 @@ public:
void close() { void close() {
ipc::detail::condition::close(); ipc::detail::condition::close();
wait_h_.release();
cnt_h_ .release(); cnt_h_ .release();
wait_h_.release();
} }
bool wait(mutex_impl& mtx, std::size_t tm = invalid_value) { bool wait(mutex_impl& mtx, std::size_t tm = invalid_value) {
@ -65,6 +71,17 @@ class object_impl {
}; };
public: public:
static void remove(char const * name) {
{
ipc::shm::handle h { name, sizeof(info_t) };
if (h.valid()) {
auto info = static_cast<info_t*>(h.get());
info->object_.close();
}
}
ipc::shm::remove(name);
}
T& object() { T& object() {
return static_cast<info_t*>(h_.get())->object_; return static_cast<info_t*>(h_.get())->object_;
} }
@ -118,6 +135,11 @@ class semaphore_impl {
} }
public: 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) { bool open(char const * name, long count) {
name_ = name; name_ = name;
if (!opened_.acquire(("__SEMAPHORE_IMPL_CNT__" + name_).c_str(), sizeof(std::atomic<unsigned>))) { if (!opened_.acquire(("__SEMAPHORE_IMPL_CNT__" + name_).c_str(), sizeof(std::atomic<unsigned>))) {

View File

@ -11,6 +11,10 @@ public:
ipc::detail::IPC_OBJECT_TYPE_I_ h_; 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_() IPC_OBJECT_TYPE_::IPC_OBJECT_TYPE_()
: p_(p_->make()) { : p_(p_->make()) {
} }