#include "shm.h" #include #include #include #include #include #include #include #include "def.h" namespace { template using IsSame = ipc::Requires::value, R>; template constexpr auto to_tchar(std::string && str) -> IsSame { return std::move(str); } template constexpr auto to_tchar(std::string && str) -> IsSame { return std::wstring_convert>{}.from_bytes(std::move(str)); } inline auto& m2h() { thread_local std::unordered_map cache; return cache; } } // internal-linkage namespace ipc { namespace shm { void* acquire(char const * name, std::size_t size) { if (name == nullptr || name[0] == '\0' || size == 0) { return nullptr; } HANDLE h = ::CreateFileMapping(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE | SEC_COMMIT, 0, static_cast(size), to_tchar(std::string{"__SHM__"} + name).c_str()); if (h == NULL) { return nullptr; } LPVOID mem = ::MapViewOfFile(h, FILE_MAP_ALL_ACCESS, 0, 0, 0); if (mem == NULL) { ::CloseHandle(h); return nullptr; } m2h().emplace(mem, h); return mem; } void release(void* mem, std::size_t /*size*/) { if (mem == nullptr) { return; } auto& cc = m2h(); auto it = cc.find(mem); if (it == cc.end()) { return; } ::UnmapViewOfFile(mem); ::CloseHandle(it->second); cc.erase(it); } } // namespace shm } // namespace ipc