Skip to content

Commit

Permalink
Added a cleanup interface for the synchronization facilities
Browse files Browse the repository at this point in the history
  • Loading branch information
mutouyun committed Nov 17, 2024
1 parent 29678f1 commit e1f377d
Show file tree
Hide file tree
Showing 16 changed files with 146 additions and 6 deletions.
3 changes: 3 additions & 0 deletions include/libipc/condition.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,9 @@ class IPC_EXPORT condition {
bool open(char const *name) noexcept;
void close() noexcept;

void clear() noexcept;
static void clear_storage(char const * name) noexcept;

bool wait(ipc::sync::mutex &mtx, std::uint64_t tm = ipc::invalid_value) noexcept;
bool notify(ipc::sync::mutex &mtx) noexcept;
bool broadcast(ipc::sync::mutex &mtx) noexcept;
Expand Down
3 changes: 3 additions & 0 deletions include/libipc/mutex.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,9 @@ class IPC_EXPORT mutex {
bool open(char const *name) noexcept;
void close() noexcept;

void clear() noexcept;
static void clear_storage(char const * name) noexcept;

bool lock(std::uint64_t tm = ipc::invalid_value) noexcept;
bool try_lock() noexcept(false); // std::system_error
bool unlock() noexcept;
Expand Down
3 changes: 3 additions & 0 deletions include/libipc/semaphore.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,9 @@ class IPC_EXPORT semaphore {
bool open(char const *name, std::uint32_t count = 0) noexcept;
void close() noexcept;

void clear() noexcept;
static void clear_storage(char const * name) noexcept;

bool wait(std::uint64_t tm = ipc::invalid_value) noexcept;
bool post(std::uint32_t count = 1) noexcept;

Expand Down
19 changes: 18 additions & 1 deletion src/libipc/platform/linux/mutex.h
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,7 @@ class mutex {
}

template <typename F>
void release_mutex(ipc::string const &name, F &&clear) {
static void release_mutex(ipc::string const &name, F &&clear) {
if (name.empty()) return;
auto &info = curr_prog::get();
IPC_UNUSED_ std::lock_guard<std::mutex> guard {info.lock};
Expand Down Expand Up @@ -192,6 +192,23 @@ class mutex {
ref_ = nullptr;
}

void clear() noexcept {
if (mutex_ != nullptr) {
if (mutex_->name() != nullptr) {
release_mutex(mutex_->name(), [] { return true; });
}
mutex_->clear();
}
mutex_ = nullptr;
ref_ = nullptr;
}

static void clear_storage(char const *name) noexcept {
if (name == nullptr) return;
release_mutex(name, [] { return true; });
robust_mutex::clear_storage(name);
}

bool lock(std::uint64_t tm) noexcept {
if (!valid()) return false;
return mutex_->lock(tm);
Expand Down
9 changes: 9 additions & 0 deletions src/libipc/platform/linux/sync_obj_impl.h
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,15 @@ class obj_impl {
shm_.release();
h_ = nullptr;
}

void clear() noexcept {
shm_.clear(); // Make sure the storage is cleaned up.
h_ = nullptr;
}

static void clear_storage(char const *name) noexcept {
ipc::shm::handle::clear_storage(name);
}
};

} // namespace sync
Expand Down
15 changes: 15 additions & 0 deletions src/libipc/platform/posix/condition.h
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,21 @@ class condition {
cond_ = nullptr;
}

void clear() noexcept {
if ((shm_.ref() <= 1) && cond_ != nullptr) {
int eno;
if ((eno = ::pthread_cond_destroy(cond_)) != 0) {
ipc::error("fail pthread_cond_destroy[%d]\n", eno);
}
}
shm_.clear(); // Make sure the storage is cleaned up.
cond_ = nullptr;
}

static void clear_storage(char const *name) noexcept {
ipc::shm::handle::clear_storage(name);
}

bool wait(ipc::sync::mutex &mtx, std::uint64_t tm) noexcept {
if (!valid()) return false;
switch (tm) {
Expand Down
26 changes: 25 additions & 1 deletion src/libipc/platform/posix/mutex.h
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ class mutex {
}

template <typename F>
void release_mutex(ipc::string const &name, F &&clear) {
static void release_mutex(ipc::string const &name, F &&clear) {
if (name.empty()) return;
auto &info = curr_prog::get();
IPC_UNUSED_ std::lock_guard<std::mutex> guard {info.lock};
Expand Down Expand Up @@ -169,6 +169,30 @@ class mutex {
mutex_ = nullptr;
}

void clear() noexcept {
if ((shm_ != nullptr) && (mutex_ != nullptr)) {
if (shm_->name() != nullptr) {
release_mutex(shm_->name(), [this] {
int eno;
if ((eno = ::pthread_mutex_destroy(mutex_)) != 0) {
ipc::error("fail pthread_mutex_destroy[%d]\n", eno);
}
return true;
});
}
shm_->clear();
}
shm_ = nullptr;
ref_ = nullptr;
mutex_ = nullptr;
}

static void clear_storage(char const *name) noexcept {
if (name == nullptr) return;
release_mutex(name, [] { return true; });
ipc::shm::handle::clear_storage(name);
}

bool lock(std::uint64_t tm) noexcept {
if (!valid()) return false;
for (;;) {
Expand Down
18 changes: 18 additions & 0 deletions src/libipc/platform/posix/semaphore_impl.h
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,24 @@ class semaphore {
}
}

void clear() noexcept {
if (valid()) {
if (::sem_close(h_) != 0) {
ipc::error("fail sem_close[%d]: %s\n", errno);
}
h_ = SEM_FAILED;
}
char const *name = shm_.name();
if (name == nullptr) return;
::sem_unlink(name);
shm_.clear(); // Make sure the storage is cleaned up.
}

static void clear_storage(char const *name) noexcept {
::sem_unlink(name);
ipc::shm::handle::clear_storage(name);
}

bool wait(std::uint64_t tm) noexcept {
if (!valid()) return false;
if (tm == invalid_value) {
Expand Down
2 changes: 1 addition & 1 deletion src/libipc/platform/posix/shm_posix.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -188,7 +188,7 @@ void remove(id_t id) noexcept {
}
}

void remove(char const * name) {
void remove(char const * name) noexcept {
if (!is_valid_string(name)) {
ipc::error("fail remove: name is empty\n");
return;
Expand Down
10 changes: 10 additions & 0 deletions src/libipc/platform/win/condition.h
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,16 @@ class condition {
shm_.release();
}

void clear() noexcept {
close();
}

static void clear_storage(char const *name) noexcept {
ipc::shm::handle::clear_storage(name);
ipc::sync::mutex::clear_storage(name);
ipc::sync::semaphore::clear_storage(name);
}

bool wait(ipc::sync::mutex &mtx, std::uint64_t tm) noexcept {
if (!valid()) return false;
auto &cnt = counter();
Expand Down
7 changes: 7 additions & 0 deletions src/libipc/platform/win/mutex.h
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,13 @@ class mutex {
h_ = NULL;
}

void clear() noexcept {
close();
}

static void clear_storage(char const */*name*/) noexcept {
}

bool lock(std::uint64_t tm) noexcept {
DWORD ret, ms = (tm == invalid_value) ? INFINITE : static_cast<DWORD>(tm);
for(;;) {
Expand Down
7 changes: 7 additions & 0 deletions src/libipc/platform/win/semaphore.h
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,13 @@ class semaphore {
h_ = NULL;
}

void clear() noexcept {
close();
}

static void clear_storage(char const */*name*/) noexcept {
}

bool wait(std::uint64_t tm) noexcept {
DWORD ret, ms = (tm == invalid_value) ? INFINITE : static_cast<DWORD>(tm);
switch ((ret = ::WaitForSingleObject(h_, ms))) {
Expand Down
6 changes: 3 additions & 3 deletions src/libipc/platform/win/shm_win.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ void * get_mem(id_t id, std::size_t * size) {
return static_cast<void *>(mem);
}

std::int32_t release(id_t id) {
std::int32_t release(id_t id) noexcept {
if (id == nullptr) {
ipc::error("fail release: invalid id (null)\n");
return -1;
Expand All @@ -120,15 +120,15 @@ std::int32_t release(id_t id) {
return 0;
}

void remove(id_t id) {
void remove(id_t id) noexcept {
if (id == nullptr) {
ipc::error("fail release: invalid id (null)\n");
return;
}
release(id);
}

void remove(char const * name) {
void remove(char const * name) noexcept {
if (!is_valid_string(name)) {
ipc::error("fail remove: name is empty\n");
return;
Expand Down
8 changes: 8 additions & 0 deletions src/libipc/sync/condition.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,14 @@ void condition::close() noexcept {
impl(p_)->cond_.close();
}

void condition::clear() noexcept {
impl(p_)->cond_.clear();
}

void condition::clear_storage(char const * name) noexcept {
ipc::detail::sync::condition::clear_storage(name);
}

bool condition::wait(ipc::sync::mutex &mtx, std::uint64_t tm) noexcept {
return impl(p_)->cond_.wait(mtx, tm);
}
Expand Down
8 changes: 8 additions & 0 deletions src/libipc/sync/mutex.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,14 @@ void mutex::close() noexcept {
impl(p_)->lock_.close();
}

void mutex::clear() noexcept {
impl(p_)->lock_.clear();
}

void mutex::clear_storage(char const * name) noexcept {
ipc::detail::sync::mutex::clear_storage(name);
}

bool mutex::lock(std::uint64_t tm) noexcept {
return impl(p_)->lock_.lock(tm);
}
Expand Down
8 changes: 8 additions & 0 deletions src/libipc/sync/semaphore.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,14 @@ void semaphore::close() noexcept {
impl(p_)->sem_.close();
}

void semaphore::clear() noexcept {
impl(p_)->sem_.clear();
}

void semaphore::clear_storage(char const * name) noexcept {
ipc::detail::sync::semaphore::clear_storage(name);
}

bool semaphore::wait(std::uint64_t tm) noexcept {
return impl(p_)->sem_.wait(tm);
}
Expand Down

0 comments on commit e1f377d

Please sign in to comment.