mirror of
https://github.com/mutouyun/cpp-ipc.git
synced 2025-12-06 08:46:45 +08:00
Complete the implementation of the clean interface and add unit tests
This commit is contained in:
parent
28fdf17279
commit
5e5b347636
@ -19,7 +19,7 @@ enum : unsigned {
|
|||||||
|
|
||||||
template <typename Flag>
|
template <typename Flag>
|
||||||
struct IPC_EXPORT chan_impl {
|
struct IPC_EXPORT chan_impl {
|
||||||
static ipc::handle_t inited();
|
static ipc::handle_t init_first();
|
||||||
|
|
||||||
static bool connect (ipc::handle_t * ph, char const * name, unsigned mode);
|
static bool connect (ipc::handle_t * ph, char const * name, unsigned mode);
|
||||||
static bool connect (ipc::handle_t * ph, prefix, char const * name, unsigned mode);
|
static bool connect (ipc::handle_t * ph, prefix, char const * name, unsigned mode);
|
||||||
@ -29,6 +29,9 @@ struct IPC_EXPORT chan_impl {
|
|||||||
|
|
||||||
static char const * name(ipc::handle_t h);
|
static char const * name(ipc::handle_t h);
|
||||||
|
|
||||||
|
// Release memory without waiting for the connection to disconnect.
|
||||||
|
static void release(ipc::handle_t h) noexcept;
|
||||||
|
|
||||||
// Force cleanup of all shared memory storage that handles depend on.
|
// Force cleanup of all shared memory storage that handles depend on.
|
||||||
static void clear(ipc::handle_t h) noexcept;
|
static void clear(ipc::handle_t h) noexcept;
|
||||||
static void clear_storage(char const * name) noexcept;
|
static void clear_storage(char const * name) noexcept;
|
||||||
@ -49,7 +52,7 @@ class chan_wrapper {
|
|||||||
private:
|
private:
|
||||||
using detail_t = chan_impl<Flag>;
|
using detail_t = chan_impl<Flag>;
|
||||||
|
|
||||||
ipc::handle_t h_ = detail_t::inited();
|
ipc::handle_t h_ = detail_t::init_first();
|
||||||
unsigned mode_ = ipc::sender;
|
unsigned mode_ = ipc::sender;
|
||||||
bool connected_ = false;
|
bool connected_ = false;
|
||||||
|
|
||||||
@ -88,15 +91,24 @@ public:
|
|||||||
return detail_t::name(h_);
|
return detail_t::name(h_);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Release memory without waiting for the connection to disconnect.
|
||||||
|
void release() noexcept {
|
||||||
|
detail_t::release(h_);
|
||||||
|
h_ = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
// Clear shared memory files under opened handle.
|
// Clear shared memory files under opened handle.
|
||||||
void clear() noexcept {
|
void clear() noexcept {
|
||||||
detail_t::clear(h_);
|
detail_t::clear(h_);
|
||||||
|
h_ = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Clear shared memory files under a specific name.
|
||||||
static void clear_storage(char const * name) noexcept {
|
static void clear_storage(char const * name) noexcept {
|
||||||
detail_t::clear_storage(name);
|
detail_t::clear_storage(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Clear shared memory files under a specific name with a prefix.
|
||||||
static void clear_storage(prefix pref, char const * name) noexcept {
|
static void clear_storage(prefix pref, char const * name) noexcept {
|
||||||
detail_t::clear_storage(pref, name);
|
detail_t::clear_storage(pref, name);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -395,10 +395,10 @@ struct queue_generator {
|
|||||||
conn_info_head::init();
|
conn_info_head::init();
|
||||||
if (!que_.valid()) {
|
if (!que_.valid()) {
|
||||||
que_.open(ipc::make_prefix(prefix_, {
|
que_.open(ipc::make_prefix(prefix_, {
|
||||||
"QU_CONN__",
|
"QU_CONN__",
|
||||||
ipc::to_string(DataSize), "__",
|
this->name_,
|
||||||
ipc::to_string(AlignSize), "__",
|
"__", ipc::to_string(DataSize),
|
||||||
this->name_}).c_str());
|
"__", ipc::to_string(AlignSize)}).c_str());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -408,11 +408,11 @@ struct queue_generator {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void clear_storage(char const * prefix, char const * name) noexcept {
|
static void clear_storage(char const * prefix, char const * name) noexcept {
|
||||||
queue_t::clear_storage(ipc::make_prefix(prefix, {
|
queue_t::clear_storage(ipc::make_prefix(ipc::make_string(prefix), {
|
||||||
"QU_CONN__",
|
"QU_CONN__",
|
||||||
ipc::to_string(DataSize), "__",
|
ipc::make_string(name),
|
||||||
ipc::to_string(AlignSize), "__",
|
"__", ipc::to_string(DataSize),
|
||||||
name}).c_str());
|
"__", ipc::to_string(AlignSize)}).c_str());
|
||||||
conn_info_head::clear_storage(prefix, name);
|
conn_info_head::clear_storage(prefix, name);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -489,8 +489,7 @@ static bool reconnect(ipc::handle_t * ph, bool start_to_recv) {
|
|||||||
return que->ready_sending();
|
return que->ready_sending();
|
||||||
}
|
}
|
||||||
|
|
||||||
static void destroy(ipc::handle_t h) {
|
static void destroy(ipc::handle_t h) noexcept {
|
||||||
disconnect(h);
|
|
||||||
ipc::mem::free(info_of(h));
|
ipc::mem::free(info_of(h));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -733,7 +732,7 @@ using policy_t = ipc::policy::choose<ipc::circ::elem_array, Flag>;
|
|||||||
namespace ipc {
|
namespace ipc {
|
||||||
|
|
||||||
template <typename Flag>
|
template <typename Flag>
|
||||||
ipc::handle_t chan_impl<Flag>::inited() {
|
ipc::handle_t chan_impl<Flag>::init_first() {
|
||||||
ipc::detail::waiter::init();
|
ipc::detail::waiter::init();
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
@ -760,6 +759,12 @@ void chan_impl<Flag>::disconnect(ipc::handle_t h) {
|
|||||||
|
|
||||||
template <typename Flag>
|
template <typename Flag>
|
||||||
void chan_impl<Flag>::destroy(ipc::handle_t h) {
|
void chan_impl<Flag>::destroy(ipc::handle_t h) {
|
||||||
|
disconnect(h);
|
||||||
|
detail_impl<policy_t<Flag>>::destroy(h);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename Flag>
|
||||||
|
void chan_impl<Flag>::release(ipc::handle_t h) noexcept {
|
||||||
detail_impl<policy_t<Flag>>::destroy(h);
|
detail_impl<policy_t<Flag>>::destroy(h);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -195,9 +195,11 @@ public:
|
|||||||
void clear() noexcept {
|
void clear() noexcept {
|
||||||
if (mutex_ != nullptr) {
|
if (mutex_ != nullptr) {
|
||||||
if (mutex_->name() != nullptr) {
|
if (mutex_->name() != nullptr) {
|
||||||
release_mutex(mutex_->name(), [] { return true; });
|
release_mutex(mutex_->name(), [this] {
|
||||||
}
|
mutex_->clear();
|
||||||
mutex_->clear();
|
return true;
|
||||||
|
});
|
||||||
|
} else mutex_->clear();
|
||||||
}
|
}
|
||||||
mutex_ = nullptr;
|
mutex_ = nullptr;
|
||||||
ref_ = nullptr;
|
ref_ = nullptr;
|
||||||
|
|||||||
@ -177,10 +177,10 @@ public:
|
|||||||
if ((eno = ::pthread_mutex_destroy(mutex_)) != 0) {
|
if ((eno = ::pthread_mutex_destroy(mutex_)) != 0) {
|
||||||
ipc::error("fail pthread_mutex_destroy[%d]\n", eno);
|
ipc::error("fail pthread_mutex_destroy[%d]\n", eno);
|
||||||
}
|
}
|
||||||
|
shm_->clear();
|
||||||
return true;
|
return true;
|
||||||
});
|
});
|
||||||
}
|
} else shm_->clear();
|
||||||
shm_->clear();
|
|
||||||
}
|
}
|
||||||
shm_ = nullptr;
|
shm_ = nullptr;
|
||||||
ref_ = nullptr;
|
ref_ = nullptr;
|
||||||
|
|||||||
@ -151,6 +151,50 @@ void test_sr(char const * name, int s_cnt, int r_cnt) {
|
|||||||
|
|
||||||
} // internal-linkage
|
} // internal-linkage
|
||||||
|
|
||||||
|
TEST(IPC, clear) {
|
||||||
|
{
|
||||||
|
chan<relat::single, relat::single, trans::unicast> c{"ssu"};
|
||||||
|
EXPECT_TRUE(ipc_ut::expect_exist("__IPC_SHM__AC_CONN__ssu", true));
|
||||||
|
EXPECT_TRUE(ipc_ut::expect_exist("__IPC_SHM__CC_CONN__ssu_WAITER_COND_", true));
|
||||||
|
EXPECT_TRUE(ipc_ut::expect_exist("__IPC_SHM__CC_CONN__ssu_WAITER_LOCK_", true));
|
||||||
|
EXPECT_TRUE(ipc_ut::expect_exist("__IPC_SHM__RD_CONN__ssu_WAITER_COND_", true));
|
||||||
|
EXPECT_TRUE(ipc_ut::expect_exist("__IPC_SHM__RD_CONN__ssu_WAITER_LOCK_", true));
|
||||||
|
EXPECT_TRUE(ipc_ut::expect_exist("__IPC_SHM__WT_CONN__ssu_WAITER_COND_", true));
|
||||||
|
EXPECT_TRUE(ipc_ut::expect_exist("__IPC_SHM__WT_CONN__ssu_WAITER_LOCK_", true));
|
||||||
|
EXPECT_TRUE(ipc_ut::expect_exist("__IPC_SHM__QU_CONN__ssu__64__16", true));
|
||||||
|
c.clear();
|
||||||
|
EXPECT_TRUE(ipc_ut::expect_exist("__IPC_SHM__AC_CONN__ssu", false));
|
||||||
|
EXPECT_TRUE(ipc_ut::expect_exist("__IPC_SHM__CC_CONN__ssu_WAITER_COND_", false));
|
||||||
|
EXPECT_TRUE(ipc_ut::expect_exist("__IPC_SHM__CC_CONN__ssu_WAITER_LOCK_", false));
|
||||||
|
EXPECT_TRUE(ipc_ut::expect_exist("__IPC_SHM__RD_CONN__ssu_WAITER_COND_", false));
|
||||||
|
EXPECT_TRUE(ipc_ut::expect_exist("__IPC_SHM__RD_CONN__ssu_WAITER_LOCK_", false));
|
||||||
|
EXPECT_TRUE(ipc_ut::expect_exist("__IPC_SHM__WT_CONN__ssu_WAITER_COND_", false));
|
||||||
|
EXPECT_TRUE(ipc_ut::expect_exist("__IPC_SHM__WT_CONN__ssu_WAITER_LOCK_", false));
|
||||||
|
EXPECT_TRUE(ipc_ut::expect_exist("__IPC_SHM__QU_CONN__ssu__64__16", false));
|
||||||
|
}
|
||||||
|
{
|
||||||
|
chan<relat::single, relat::single, trans::unicast> c{"ssu"};
|
||||||
|
EXPECT_TRUE(ipc_ut::expect_exist("__IPC_SHM__AC_CONN__ssu", true));
|
||||||
|
EXPECT_TRUE(ipc_ut::expect_exist("__IPC_SHM__CC_CONN__ssu_WAITER_COND_", true));
|
||||||
|
EXPECT_TRUE(ipc_ut::expect_exist("__IPC_SHM__CC_CONN__ssu_WAITER_LOCK_", true));
|
||||||
|
EXPECT_TRUE(ipc_ut::expect_exist("__IPC_SHM__RD_CONN__ssu_WAITER_COND_", true));
|
||||||
|
EXPECT_TRUE(ipc_ut::expect_exist("__IPC_SHM__RD_CONN__ssu_WAITER_LOCK_", true));
|
||||||
|
EXPECT_TRUE(ipc_ut::expect_exist("__IPC_SHM__WT_CONN__ssu_WAITER_COND_", true));
|
||||||
|
EXPECT_TRUE(ipc_ut::expect_exist("__IPC_SHM__WT_CONN__ssu_WAITER_LOCK_", true));
|
||||||
|
EXPECT_TRUE(ipc_ut::expect_exist("__IPC_SHM__QU_CONN__ssu__64__16", true));
|
||||||
|
chan<relat::single, relat::single, trans::unicast>::clear_storage("ssu");
|
||||||
|
EXPECT_TRUE(ipc_ut::expect_exist("__IPC_SHM__AC_CONN__ssu", false));
|
||||||
|
EXPECT_TRUE(ipc_ut::expect_exist("__IPC_SHM__CC_CONN__ssu_WAITER_COND_", false));
|
||||||
|
EXPECT_TRUE(ipc_ut::expect_exist("__IPC_SHM__CC_CONN__ssu_WAITER_LOCK_", false));
|
||||||
|
EXPECT_TRUE(ipc_ut::expect_exist("__IPC_SHM__RD_CONN__ssu_WAITER_COND_", false));
|
||||||
|
EXPECT_TRUE(ipc_ut::expect_exist("__IPC_SHM__RD_CONN__ssu_WAITER_LOCK_", false));
|
||||||
|
EXPECT_TRUE(ipc_ut::expect_exist("__IPC_SHM__WT_CONN__ssu_WAITER_COND_", false));
|
||||||
|
EXPECT_TRUE(ipc_ut::expect_exist("__IPC_SHM__WT_CONN__ssu_WAITER_LOCK_", false));
|
||||||
|
EXPECT_TRUE(ipc_ut::expect_exist("__IPC_SHM__QU_CONN__ssu__64__16", false));
|
||||||
|
c.release(); // Call this interface to prevent destruction-time exceptions.
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
TEST(IPC, basic_ssu) {
|
TEST(IPC, basic_ssu) {
|
||||||
test_basic<relat::single, relat::single, trans::unicast >("ssu");
|
test_basic<relat::single, relat::single, trans::unicast >("ssu");
|
||||||
}
|
}
|
||||||
|
|||||||
@ -205,4 +205,4 @@ TEST(Sync, ConditionRobust) {
|
|||||||
ASSERT_TRUE(lock.unlock());
|
ASSERT_TRUE(lock.unlock());
|
||||||
printf("XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 6\n");
|
printf("XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 6\n");
|
||||||
unlock.join();
|
unlock.join();
|
||||||
}
|
}
|
||||||
|
|||||||
@ -4,8 +4,6 @@
|
|||||||
#include "libipc/waiter.h"
|
#include "libipc/waiter.h"
|
||||||
#include "test.h"
|
#include "test.h"
|
||||||
|
|
||||||
namespace {
|
|
||||||
|
|
||||||
TEST(Waiter, broadcast) {
|
TEST(Waiter, broadcast) {
|
||||||
for (int i = 0; i < 10; ++i) {
|
for (int i = 0; i < 10; ++i) {
|
||||||
ipc::detail::waiter waiter;
|
ipc::detail::waiter waiter;
|
||||||
@ -65,4 +63,23 @@ TEST(Waiter, quit_waiting) {
|
|||||||
std::cout << "quit... \n";
|
std::cout << "quit... \n";
|
||||||
}
|
}
|
||||||
|
|
||||||
} // internal-linkage
|
TEST(Waiter, clear) {
|
||||||
|
{
|
||||||
|
ipc::detail::waiter w{"my-waiter"};
|
||||||
|
ASSERT_TRUE(w.valid());
|
||||||
|
EXPECT_TRUE(ipc_ut::expect_exist("my-waiter_WAITER_COND_", true));
|
||||||
|
EXPECT_TRUE(ipc_ut::expect_exist("my-waiter_WAITER_LOCK_", true));
|
||||||
|
w.clear();
|
||||||
|
ASSERT_TRUE(!w.valid());
|
||||||
|
EXPECT_TRUE(ipc_ut::expect_exist("my-waiter_WAITER_COND_", false));
|
||||||
|
EXPECT_TRUE(ipc_ut::expect_exist("my-waiter_WAITER_LOCK_", false));
|
||||||
|
}
|
||||||
|
{
|
||||||
|
ipc::detail::waiter w{"my-waiter"};
|
||||||
|
EXPECT_TRUE(ipc_ut::expect_exist("my-waiter_WAITER_COND_", true));
|
||||||
|
EXPECT_TRUE(ipc_ut::expect_exist("my-waiter_WAITER_LOCK_", true));
|
||||||
|
ipc::detail::waiter::clear_storage("my-waiter");
|
||||||
|
EXPECT_TRUE(ipc_ut::expect_exist("my-waiter_WAITER_COND_", false));
|
||||||
|
EXPECT_TRUE(ipc_ut::expect_exist("my-waiter_WAITER_LOCK_", false));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user