mirror of
https://github.com/mutouyun/cpp-ipc.git
synced 2025-12-06 16:56:45 +08:00
Added a cleanup interface for shared memory handles
This commit is contained in:
parent
805490605e
commit
5071fb5db6
@ -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;
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -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);
|
||||
}
|
||||
};
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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);
|
||||
}
|
||||
|
||||
|
||||
@ -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_;
|
||||
}
|
||||
|
||||
24
test/test.h
24
test/test.h
@ -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
|
||||
@ -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
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user