winapi_common
shmem.hpp
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 #pragma once
7 
8 #include "handle.hpp"
9 
10 #include <cstddef>
11 #include <memory>
12 #include <string>
13 #include <type_traits>
14 #include <utility>
15 
16 namespace winapi {
17 
19 class SharedMemory {
20 public:
26  static SharedMemory create(const std::string& name, std::size_t nb);
31  static SharedMemory open(const std::string& name);
32 
34  void* get() const { return m_addr.get(); }
36  void* ptr() const { return get(); }
37 
38 private:
39  struct Unmap {
40  void operator()(void*) const;
41  };
42 
43  SharedMemory() = default;
44 
45  SharedMemory(Handle&& handle, void* addr) : m_handle{std::move(handle)}, m_addr{addr} {}
46 
47  Handle m_handle;
48  std::unique_ptr<void, Unmap> m_addr;
49 };
50 
52 template <typename T>
53 class SharedObject {
54 public:
55  typedef typename std::aligned_storage<sizeof(T), __alignof(T)>::type AlignedType;
56 
62  template <typename... Args>
63  static SharedObject create(const std::string& name, Args&&... args) {
64  SharedObject obj{SharedMemory::create(name, sizeof(AlignedType))};
65  new (obj.ptr()) T(std::forward<Args>(args)...);
66  obj.m_destruct = true;
67  return obj;
68  }
69 
74  static SharedObject open(const std::string& name) {
76  return obj;
77  }
78 
79  SharedObject(SharedObject&& other) noexcept = default;
80  SharedObject& operator=(const SharedObject& other) noexcept = default;
81  SharedObject(const SharedObject&) = delete;
82 
83  ~SharedObject() {
84  if (m_destruct && ptr()) {
85  ptr()->~T();
86  }
87  }
88 
90  T* ptr() const { return reinterpret_cast<T*>(m_shmem.ptr()); }
92  T& get() const { return *ptr(); }
93 
94  T* operator->() const { return ptr(); }
95  T& operator*() const { return get(); }
96 
97 private:
98  explicit SharedObject(SharedMemory&& shmem) : m_shmem(std::move(shmem)) {}
99 
100  SharedMemory m_shmem;
101  // Destruct only once, no matter the number of mappings.
102  bool m_destruct = false;
103 };
104 
105 } // namespace winapi
Named shared memory region.
Definition: shmem.hpp:19
void * ptr() const
Definition: shmem.hpp:36
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
void * get() const
Definition: shmem.hpp:34
Easy way to represent a C++ object as a shared memory region.
Definition: shmem.hpp:53
static SharedObject open(const std::string &name)
Definition: shmem.hpp:74
T * ptr() const
Definition: shmem.hpp:90
T & get() const
Definition: shmem.hpp:92
static SharedObject create(const std::string &name, Args &&... args)
Definition: shmem.hpp:63