From 89f1c684d73ce275671f2cf5c312dd75af1f18d8 Mon Sep 17 00:00:00 2001 From: Egor Tensin Date: Wed, 21 Oct 2020 03:39:05 +0300 Subject: add Shared{Memory,Object} classes --- src/shmem.cpp | 88 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 88 insertions(+) create mode 100644 src/shmem.cpp (limited to 'src') diff --git a/src/shmem.cpp b/src/shmem.cpp new file mode 100644 index 0000000..552351d --- /dev/null +++ b/src/shmem.cpp @@ -0,0 +1,88 @@ +// Copyright (c) 2020 Egor Tensin +// This file is part of the "winapi-common" project. +// For details, see https://github.com/egor-tensin/winapi-common. +// Distributed under the MIT License. + +#include +#include +#include +#include +#include + +#include + +#include + +#include +#include +#include +#include + +namespace winapi { +namespace { + +void* do_map(const Handle& mapping, std::size_t nb = 0) { + const auto addr = ::MapViewOfFile(static_cast(mapping), FILE_MAP_ALL_ACCESS, 0, 0, nb); + + if (addr == NULL) { + throw error::windows(GetLastError(), "MapViewOfFile"); + } + + return addr; +} + +} // namespace + +void SharedMemory::Unmap::operator()(void* ptr) const { + const auto ret = ::UnmapViewOfFile(ptr); + assert(ret); + WINAPI_UNUSED_PARAMETER(ret); +}; + +SharedMemory SharedMemory::create(const std::string& name, std::size_t nb) { + const auto nb64 = static_cast(nb); + static_assert(sizeof(nb64) == 2 * sizeof(DWORD), "sizeof(DWORD) != 32"); + + const auto nb_low = static_cast(nb64); + const auto nb_high = static_cast(nb64 >> 32); + + const auto h_mapping = ::CreateFileMappingW( + INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, nb_high, nb_low, widen(name).c_str()); + + if (h_mapping == NULL) { + throw error::windows(GetLastError(), "CreateFileMappingW"); + } + + Handle mapping{h_mapping}; + const auto addr = do_map(mapping); + return {std::move(mapping), addr}; +} + +SharedMemory SharedMemory::open(const std::string& name) { + const auto h_mapping = ::OpenFileMappingW(FILE_MAP_ALL_ACCESS, FALSE, widen(name).c_str()); + + if (h_mapping == NULL) { + throw error::windows(GetLastError(), "OpenFileMappingW"); + } + + Handle mapping{h_mapping}; + const auto addr = do_map(mapping); + return {std::move(mapping), addr}; +} + +SharedMemory::SharedMemory(SharedMemory&& other) BOOST_NOEXCEPT_OR_NOTHROW { + swap(other); +} + +SharedMemory& SharedMemory::operator=(SharedMemory other) BOOST_NOEXCEPT_OR_NOTHROW { + swap(other); + return *this; +} + +void SharedMemory::swap(SharedMemory& other) BOOST_NOEXCEPT_OR_NOTHROW { + using std::swap; + swap(m_handle, other.m_handle); + swap(m_addr, other.m_addr); +} + +} // namespace winapi -- cgit v1.2.3