Skip to content

Commit e1f377d

Browse files
committed
Added a cleanup interface for the synchronization facilities
1 parent 29678f1 commit e1f377d

16 files changed

+146
-6
lines changed

include/libipc/condition.h

+3
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,9 @@ class IPC_EXPORT condition {
2626
bool open(char const *name) noexcept;
2727
void close() noexcept;
2828

29+
void clear() noexcept;
30+
static void clear_storage(char const * name) noexcept;
31+
2932
bool wait(ipc::sync::mutex &mtx, std::uint64_t tm = ipc::invalid_value) noexcept;
3033
bool notify(ipc::sync::mutex &mtx) noexcept;
3134
bool broadcast(ipc::sync::mutex &mtx) noexcept;

include/libipc/mutex.h

+3
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,9 @@ class IPC_EXPORT mutex {
2626
bool open(char const *name) noexcept;
2727
void close() noexcept;
2828

29+
void clear() noexcept;
30+
static void clear_storage(char const * name) noexcept;
31+
2932
bool lock(std::uint64_t tm = ipc::invalid_value) noexcept;
3033
bool try_lock() noexcept(false); // std::system_error
3134
bool unlock() noexcept;

include/libipc/semaphore.h

+3
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,9 @@ class IPC_EXPORT semaphore {
2525
bool open(char const *name, std::uint32_t count = 0) noexcept;
2626
void close() noexcept;
2727

28+
void clear() noexcept;
29+
static void clear_storage(char const * name) noexcept;
30+
2831
bool wait(std::uint64_t tm = ipc::invalid_value) noexcept;
2932
bool post(std::uint32_t count = 1) noexcept;
3033

src/libipc/platform/linux/mutex.h

+18-1
Original file line numberDiff line numberDiff line change
@@ -136,7 +136,7 @@ class mutex {
136136
}
137137

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

195+
void clear() noexcept {
196+
if (mutex_ != nullptr) {
197+
if (mutex_->name() != nullptr) {
198+
release_mutex(mutex_->name(), [] { return true; });
199+
}
200+
mutex_->clear();
201+
}
202+
mutex_ = nullptr;
203+
ref_ = nullptr;
204+
}
205+
206+
static void clear_storage(char const *name) noexcept {
207+
if (name == nullptr) return;
208+
release_mutex(name, [] { return true; });
209+
robust_mutex::clear_storage(name);
210+
}
211+
195212
bool lock(std::uint64_t tm) noexcept {
196213
if (!valid()) return false;
197214
return mutex_->lock(tm);

src/libipc/platform/linux/sync_obj_impl.h

+9
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,15 @@ class obj_impl {
6262
shm_.release();
6363
h_ = nullptr;
6464
}
65+
66+
void clear() noexcept {
67+
shm_.clear(); // Make sure the storage is cleaned up.
68+
h_ = nullptr;
69+
}
70+
71+
static void clear_storage(char const *name) noexcept {
72+
ipc::shm::handle::clear_storage(name);
73+
}
6574
};
6675

6776
} // namespace sync

src/libipc/platform/posix/condition.h

+15
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,21 @@ class condition {
8888
cond_ = nullptr;
8989
}
9090

91+
void clear() noexcept {
92+
if ((shm_.ref() <= 1) && cond_ != nullptr) {
93+
int eno;
94+
if ((eno = ::pthread_cond_destroy(cond_)) != 0) {
95+
ipc::error("fail pthread_cond_destroy[%d]\n", eno);
96+
}
97+
}
98+
shm_.clear(); // Make sure the storage is cleaned up.
99+
cond_ = nullptr;
100+
}
101+
102+
static void clear_storage(char const *name) noexcept {
103+
ipc::shm::handle::clear_storage(name);
104+
}
105+
91106
bool wait(ipc::sync::mutex &mtx, std::uint64_t tm) noexcept {
92107
if (!valid()) return false;
93108
switch (tm) {

src/libipc/platform/posix/mutex.h

+25-1
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ class mutex {
7171
}
7272

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

172+
void clear() noexcept {
173+
if ((shm_ != nullptr) && (mutex_ != nullptr)) {
174+
if (shm_->name() != nullptr) {
175+
release_mutex(shm_->name(), [this] {
176+
int eno;
177+
if ((eno = ::pthread_mutex_destroy(mutex_)) != 0) {
178+
ipc::error("fail pthread_mutex_destroy[%d]\n", eno);
179+
}
180+
return true;
181+
});
182+
}
183+
shm_->clear();
184+
}
185+
shm_ = nullptr;
186+
ref_ = nullptr;
187+
mutex_ = nullptr;
188+
}
189+
190+
static void clear_storage(char const *name) noexcept {
191+
if (name == nullptr) return;
192+
release_mutex(name, [] { return true; });
193+
ipc::shm::handle::clear_storage(name);
194+
}
195+
172196
bool lock(std::uint64_t tm) noexcept {
173197
if (!valid()) return false;
174198
for (;;) {

src/libipc/platform/posix/semaphore_impl.h

+18
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,24 @@ class semaphore {
6262
}
6363
}
6464

65+
void clear() noexcept {
66+
if (valid()) {
67+
if (::sem_close(h_) != 0) {
68+
ipc::error("fail sem_close[%d]: %s\n", errno);
69+
}
70+
h_ = SEM_FAILED;
71+
}
72+
char const *name = shm_.name();
73+
if (name == nullptr) return;
74+
::sem_unlink(name);
75+
shm_.clear(); // Make sure the storage is cleaned up.
76+
}
77+
78+
static void clear_storage(char const *name) noexcept {
79+
::sem_unlink(name);
80+
ipc::shm::handle::clear_storage(name);
81+
}
82+
6583
bool wait(std::uint64_t tm) noexcept {
6684
if (!valid()) return false;
6785
if (tm == invalid_value) {

src/libipc/platform/posix/shm_posix.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -188,7 +188,7 @@ void remove(id_t id) noexcept {
188188
}
189189
}
190190

191-
void remove(char const * name) {
191+
void remove(char const * name) noexcept {
192192
if (!is_valid_string(name)) {
193193
ipc::error("fail remove: name is empty\n");
194194
return;

src/libipc/platform/win/condition.h

+10
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,16 @@ class condition {
6767
shm_.release();
6868
}
6969

70+
void clear() noexcept {
71+
close();
72+
}
73+
74+
static void clear_storage(char const *name) noexcept {
75+
ipc::shm::handle::clear_storage(name);
76+
ipc::sync::mutex::clear_storage(name);
77+
ipc::sync::semaphore::clear_storage(name);
78+
}
79+
7080
bool wait(ipc::sync::mutex &mtx, std::uint64_t tm) noexcept {
7181
if (!valid()) return false;
7282
auto &cnt = counter();

src/libipc/platform/win/mutex.h

+7
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,13 @@ class mutex {
4747
h_ = NULL;
4848
}
4949

50+
void clear() noexcept {
51+
close();
52+
}
53+
54+
static void clear_storage(char const */*name*/) noexcept {
55+
}
56+
5057
bool lock(std::uint64_t tm) noexcept {
5158
DWORD ret, ms = (tm == invalid_value) ? INFINITE : static_cast<DWORD>(tm);
5259
for(;;) {

src/libipc/platform/win/semaphore.h

+7
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,13 @@ class semaphore {
4646
h_ = NULL;
4747
}
4848

49+
void clear() noexcept {
50+
close();
51+
}
52+
53+
static void clear_storage(char const */*name*/) noexcept {
54+
}
55+
4956
bool wait(std::uint64_t tm) noexcept {
5057
DWORD ret, ms = (tm == invalid_value) ? INFINITE : static_cast<DWORD>(tm);
5158
switch ((ret = ::WaitForSingleObject(h_, ms))) {

src/libipc/platform/win/shm_win.cpp

+3-3
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,7 @@ void * get_mem(id_t id, std::size_t * size) {
102102
return static_cast<void *>(mem);
103103
}
104104

105-
std::int32_t release(id_t id) {
105+
std::int32_t release(id_t id) noexcept {
106106
if (id == nullptr) {
107107
ipc::error("fail release: invalid id (null)\n");
108108
return -1;
@@ -120,15 +120,15 @@ std::int32_t release(id_t id) {
120120
return 0;
121121
}
122122

123-
void remove(id_t id) {
123+
void remove(id_t id) noexcept {
124124
if (id == nullptr) {
125125
ipc::error("fail release: invalid id (null)\n");
126126
return;
127127
}
128128
release(id);
129129
}
130130

131-
void remove(char const * name) {
131+
void remove(char const * name) noexcept {
132132
if (!is_valid_string(name)) {
133133
ipc::error("fail remove: name is empty\n");
134134
return;

src/libipc/sync/condition.cpp

+8
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,14 @@ void condition::close() noexcept {
6161
impl(p_)->cond_.close();
6262
}
6363

64+
void condition::clear() noexcept {
65+
impl(p_)->cond_.clear();
66+
}
67+
68+
void condition::clear_storage(char const * name) noexcept {
69+
ipc::detail::sync::condition::clear_storage(name);
70+
}
71+
6472
bool condition::wait(ipc::sync::mutex &mtx, std::uint64_t tm) noexcept {
6573
return impl(p_)->cond_.wait(mtx, tm);
6674
}

src/libipc/sync/mutex.cpp

+8
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,14 @@ void mutex::close() noexcept {
6161
impl(p_)->lock_.close();
6262
}
6363

64+
void mutex::clear() noexcept {
65+
impl(p_)->lock_.clear();
66+
}
67+
68+
void mutex::clear_storage(char const * name) noexcept {
69+
ipc::detail::sync::mutex::clear_storage(name);
70+
}
71+
6472
bool mutex::lock(std::uint64_t tm) noexcept {
6573
return impl(p_)->lock_.lock(tm);
6674
}

src/libipc/sync/semaphore.cpp

+8
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,14 @@ void semaphore::close() noexcept {
5959
impl(p_)->sem_.close();
6060
}
6161

62+
void semaphore::clear() noexcept {
63+
impl(p_)->sem_.clear();
64+
}
65+
66+
void semaphore::clear_storage(char const * name) noexcept {
67+
ipc::detail::sync::semaphore::clear_storage(name);
68+
}
69+
6270
bool semaphore::wait(std::uint64_t tm) noexcept {
6371
return impl(p_)->sem_.wait(tm);
6472
}

0 commit comments

Comments
 (0)