Added a cleanup interface for shared memory handles

This commit is contained in:
mutouyun 2024-11-17 17:35:29 +08:00
parent 805490605e
commit 5071fb5db6
8 changed files with 273 additions and 201 deletions

View File

@ -11,8 +11,8 @@ namespace mem {
class IPC_EXPORT pool_alloc {
public:
static void* alloc(std::size_t size);
static void free (void* p, std::size_t size);
static void* alloc(std::size_t size) noexcept;
static void free (void* p, std::size_t size) noexcept;
};
////////////////////////////////////////////////////////////////

View File

@ -17,9 +17,9 @@ enum : unsigned {
IPC_EXPORT id_t acquire(char const * name, std::size_t size, unsigned mode = create | open);
IPC_EXPORT void * get_mem(id_t id, std::size_t * size);
IPC_EXPORT std::int32_t release(id_t id);
IPC_EXPORT void remove (id_t id);
IPC_EXPORT void remove (char const * name);
IPC_EXPORT std::int32_t release(id_t id) noexcept;
IPC_EXPORT void remove (id_t id) noexcept;
IPC_EXPORT void remove (char const * name) noexcept;
IPC_EXPORT std::int32_t get_ref(id_t id);
IPC_EXPORT void sub_ref(id_t id);
@ -45,6 +45,10 @@ public:
bool acquire(char const * name, std::size_t size, unsigned mode = create | open);
std::int32_t release();
// Clean the handle file.
void clear() noexcept;
static void clear_storage(char const * name) noexcept;
void* get() const;
void attach(id_t);

View File

@ -19,17 +19,17 @@ namespace mem {
class static_alloc {
public:
static void swap(static_alloc&) {}
static void swap(static_alloc&) noexcept {}
static void* alloc(std::size_t size) {
static void* alloc(std::size_t size) noexcept {
return size ? std::malloc(size) : nullptr;
}
static void free(void* p) {
static void free(void* p) noexcept {
std::free(p);
}
static void free(void* p, std::size_t /*size*/) {
static void free(void* p, std::size_t /*size*/) noexcept {
free(p);
}
};

View File

@ -153,7 +153,7 @@ void * get_mem(id_t id, std::size_t * size) {
return 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;
@ -175,7 +175,7 @@ std::int32_t release(id_t id) {
return ret;
}
void remove(id_t id) {
void remove(id_t id) noexcept {
if (id == nullptr) {
ipc::error("fail remove: invalid id (null)\n");
return;

View File

@ -5,11 +5,11 @@
namespace ipc {
namespace mem {
void* pool_alloc::alloc(std::size_t size) {
void* pool_alloc::alloc(std::size_t size) noexcept {
return async_pool_alloc::alloc(size);
}
void pool_alloc::free(void* p, std::size_t size) {
void pool_alloc::free(void* p, std::size_t size) noexcept {
async_pool_alloc::free(p, size);
}

View File

@ -89,6 +89,18 @@ std::int32_t handle::release() {
return shm::release(detach());
}
void handle::clear() noexcept {
if (impl(p_)->id_ == nullptr) return;
shm::remove(detach());
}
void handle::clear_storage(char const * name) noexcept {
if (name == nullptr) {
return;
}
shm::remove(name);
}
void* handle::get() const {
return impl(p_)->m_;
}

View File

@ -14,6 +14,11 @@
#include "thread_pool.h"
#include "libipc/platform/detail.h"
#ifdef IPC_OS_LINUX_
#include <fcntl.h> // ::open
#endif
namespace ipc_ut {
template <typename Dur>
@ -83,4 +88,23 @@ inline static thread_pool & reader() {
return pool;
}
#ifdef IPC_OS_LINUX_
inline bool check_exist(char const *name) noexcept {
int fd = ::open((std::string{"/dev/shm/__IPC_SHM__"} + name).c_str(), O_RDONLY);
if (fd == -1) {
return false;
}
::close(fd);
return true;
}
#endif
inline bool expect_exist(char const *name, bool expected) noexcept {
#ifdef IPC_OS_LINUX_
return ipc_ut::check_exist(name) == expected;
#else
return true;
#endif
}
} // namespace ipc_ut

View File

@ -3,6 +3,7 @@
#include <thread>
#include "libipc/shm.h"
#include "test.h"
using namespace ipc::shm;
@ -99,4 +100,35 @@ TEST(SHM, mt) {
EXPECT_TRUE(memcmp(shm_hd.get(), buf, sizeof(buf)) == 0);
}
TEST(SHM, remove) {
{
auto id = ipc::shm::acquire("hello-remove", 111);
EXPECT_TRUE(ipc_ut::expect_exist("hello-remove", true));
ipc::shm::remove(id);
EXPECT_TRUE(ipc_ut::expect_exist("hello-remove", false));
}
{
auto id = ipc::shm::acquire("hello-remove", 111);
EXPECT_TRUE(ipc_ut::expect_exist("hello-remove", true));
ipc::shm::release(id);
EXPECT_TRUE(ipc_ut::expect_exist("hello-remove", true));
ipc::shm::remove("hello-remove");
EXPECT_TRUE(ipc_ut::expect_exist("hello-remove", false));
}
{
handle shm_hd;
EXPECT_TRUE(shm_hd.acquire("mt-test", 256));
EXPECT_TRUE(ipc_ut::expect_exist("mt-test", true));
shm_hd.clear();
EXPECT_TRUE(ipc_ut::expect_exist("mt-test", false));
}
{
handle shm_hd;
EXPECT_TRUE(shm_hd.acquire("mt-test", 256));
EXPECT_TRUE(ipc_ut::expect_exist("mt-test", true));
shm_hd.clear_storage("mt-test");
EXPECT_TRUE(ipc_ut::expect_exist("mt-test", false));
}
}
} // internal-linkage