diff --git a/src/libipc/platform/win/mmap.h b/src/libipc/platform/win/mmap.h index 2487e89..b0cf7f5 100644 --- a/src/libipc/platform/win/mmap.h +++ b/src/libipc/platform/win/mmap.h @@ -54,7 +54,7 @@ void mmap_close(HANDLE h) { * @param type Combinable open modes, create | open * @return File mapping object HANDLE, NULL on error */ -HANDLE mmap_open(std::string file, std::size_t size, mode::type type) noexcept { +HANDLE mmap_open(std::string const &file, std::size_t size, mode::type type) noexcept { LIBIMP_LOG_(); if (file.empty()) { log.error("file name is empty."); @@ -72,6 +72,9 @@ HANDLE mmap_open(std::string file, std::size_t size, mode::type type) noexcept { log.error("OpenFileMapping fails. error = {}", sys::error_msg(sys::error_code())); } return h; + } else if (!(type & mode::create)) { + log.error("mode type is invalid. type = {}", type); + return NULL; } /// @brief Creates or opens a named or unnamed file mapping object for a specified file. HANDLE h = ::CreateFileMapping(INVALID_HANDLE_VALUE, detail::get_sa(), PAGE_READWRITE | SEC_COMMIT, @@ -84,6 +87,7 @@ HANDLE mmap_open(std::string file, std::size_t size, mode::type type) noexcept { // (with its current size, not the specified size), and GetLastError returns ERROR_ALREADY_EXISTS. if ((type == mode::create) && (::GetLastError() == ERROR_ALREADY_EXISTS)) { mmap_close(h); + log.info("the file being created already exists. file = {}, type = {}", file, type); return NULL; } return h; @@ -148,7 +152,29 @@ void mmap_release(HANDLE h, LPCVOID mem) { } // namespace ::LIBIMP_::result shm_open(std::string name, std::size_t size, mode::type type) noexcept { - return {}; + LIBIMP_LOG_(); + auto h = mmap_open(name, size, type); + if (h == NULL) { + log.error("mmap_open failed."); + return {nullptr, *sys::error_code()}; + } + auto mem = mmap_memof(h); + if (mem == NULL) { + log.warning("mmap_memof failed."); + } + return new shm_handle{std::move(name), mmap_sizeof(mem), mem, h}; +} + +::LIBIMP_::result_code shm_close(shm_t h) noexcept { + LIBIMP_LOG_(); + if (h == nullptr) { + log.error("shm handle is null."); + return {}; + } + auto shm = static_cast(h); + mmap_release(shm->h_fmap, shm->memp); + delete shm; + return {true}; } LIBIPC_NAMESPACE_END_ diff --git a/src/libipc/shm.cpp b/src/libipc/shm.cpp index dad96d9..9522e7c 100644 --- a/src/libipc/shm.cpp +++ b/src/libipc/shm.cpp @@ -1,3 +1,6 @@ + +#include "libimp/log.h" + #include "libimp/detect_plat.h" #if defined(LIBIMP_OS_WIN) #include "libipc/platform/win/mmap.h" @@ -7,6 +10,34 @@ LIBIPC_NAMESPACE_BEG_ +void *shm_get(shm_t h) noexcept { + LIBIMP_LOG_(); + if (h == nullptr) { + log.error("shm handle is null."); + return {}; + } + auto shm = static_cast(h); + return shm->memp; +} +std::size_t shm_size(shm_t h) noexcept { + LIBIMP_LOG_(); + if (h == nullptr) { + log.error("shm handle is null."); + return {}; + } + auto shm = static_cast(h); + return shm->f_sz; +} + +std::string shm_file(shm_t h) noexcept { + LIBIMP_LOG_(); + if (h == nullptr) { + log.error("shm handle is null."); + return {}; + } + auto shm = static_cast(h); + return shm->file; +} LIBIPC_NAMESPACE_END_ diff --git a/test/test_ipc_shm.cpp b/test/test_ipc_shm.cpp index 1e5c95f..2495cb4 100644 --- a/test/test_ipc_shm.cpp +++ b/test/test_ipc_shm.cpp @@ -4,4 +4,27 @@ #include "libipc/shm.h" TEST(shm, create_close) { + EXPECT_FALSE(ipc::shm_open("hello-ipc-shm", 1024, ipc::mode::none)); + + auto shm1 = ipc::shm_open("hello-ipc-shm", 1024, ipc::mode::create | ipc::mode::open); + EXPECT_TRUE(shm1); + EXPECT_FALSE(ipc::shm_open("hello-ipc-shm", 1024, ipc::mode::create)); + + auto pt1 = ipc::shm_get(*shm1); + EXPECT_TRUE(ipc::shm_size(*shm1) >= 1024); + EXPECT_NE(pt1, nullptr); + *(int *)pt1 = 0; + + auto shm2 = ipc::shm_open("hello-ipc-shm", 0, ipc::mode::open); + EXPECT_TRUE(shm2); + EXPECT_EQ(ipc::shm_size(*shm1), ipc::shm_size(*shm2)); + auto pt2 = ipc::shm_get(*shm1); + EXPECT_NE(pt2, nullptr); + EXPECT_EQ(*(int *)pt2, 0); + *(int *)pt1 = 1234; + EXPECT_EQ(*(int *)pt2, 1234); + + EXPECT_TRUE(ipc::shm_close(*shm2)); + EXPECT_TRUE(ipc::shm_close(*shm1)); + EXPECT_FALSE(ipc::shm_close(nullptr)); } \ No newline at end of file