winapi_common
shmem.cpp
1 // Copyright (c) 2020 Egor Tensin <Egor.Tensin@gmail.com>
2 // This file is part of the "winapi-common" project.
3 // For details, see https://github.com/egor-tensin/winapi-common.
4 // Distributed under the MIT License.
5 
6 #include <winapi/error.hpp>
7 #include <winapi/handle.hpp>
8 #include <winapi/shmem.hpp>
9 #include <winapi/utf8.hpp>
10 #include <winapi/utils.hpp>
11 
12 #include <windows.h>
13 
14 #include <cstddef>
15 #include <cstdint>
16 #include <string>
17 #include <utility>
18 
19 namespace winapi {
20 namespace {
21 
22 void* do_map(const Handle& mapping, std::size_t nb = 0) {
23  const auto addr = ::MapViewOfFile(static_cast<HANDLE>(mapping), FILE_MAP_ALL_ACCESS, 0, 0, nb);
24 
25  if (addr == NULL) {
26  throw error::windows(GetLastError(), "MapViewOfFile");
27  }
28 
29  return addr;
30 }
31 
32 } // namespace
33 
34 void SharedMemory::Unmap::operator()(void* ptr) const {
35  const auto ret = ::UnmapViewOfFile(ptr);
36  assert(ret);
37  WINAPI_UNUSED_PARAMETER(ret);
38 };
39 
40 SharedMemory SharedMemory::create(const std::string& name, std::size_t nb) {
41  const auto nb64 = static_cast<std::uint64_t>(nb);
42  static_assert(sizeof(nb64) == 2 * sizeof(DWORD), "sizeof(DWORD) != 32");
43 
44  const auto nb_low = static_cast<DWORD>(nb64);
45  const auto nb_high = static_cast<DWORD>(nb64 >> 32);
46 
47  const auto mapping_impl = ::CreateFileMappingW(
48  INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, nb_high, nb_low, widen(name).c_str());
49 
50  if (mapping_impl == NULL) {
51  throw error::windows(GetLastError(), "CreateFileMappingW");
52  }
53 
54  Handle mapping{mapping_impl};
55  const auto addr = do_map(mapping);
56  return {std::move(mapping), addr};
57 }
58 
59 SharedMemory SharedMemory::open(const std::string& name) {
60  const auto mapping_impl = ::OpenFileMappingW(FILE_MAP_ALL_ACCESS, FALSE, widen(name).c_str());
61 
62  if (mapping_impl == NULL) {
63  throw error::windows(GetLastError(), "OpenFileMappingW");
64  }
65 
66  Handle mapping{mapping_impl};
67  const auto addr = do_map(mapping);
68  return {std::move(mapping), addr};
69 }
70 
71 } // namespace winapi
HANDLE wrapper.
Definition: handle.hpp:25
Named shared memory region.
Definition: shmem.hpp:19
static SharedMemory create(const std::string &name, std::size_t nb)
Definition: shmem.cpp:40
static SharedMemory open(const std::string &name)
Definition: shmem.cpp:59
Make std::system_error work with GetLastError().