add: [ipc] implementation of shm (TBD)

This commit is contained in:
mutouyun 2022-09-18 17:27:14 +08:00
parent 9f9b57cb51
commit 57d8c7a850
3 changed files with 82 additions and 2 deletions

View File

@ -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_t> shm_open(std::string name, std::size_t size, mode::type type) noexcept {
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<shm_handle *>(h);
mmap_release(shm->h_fmap, shm->memp);
delete shm;
return {true};
}
LIBIPC_NAMESPACE_END_

View File

@ -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<shm_handle *>(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<shm_handle *>(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<shm_handle *>(h);
return shm->file;
}
LIBIPC_NAMESPACE_END_

View File

@ -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));
}