VLink  2.0.0
A high-performance communication middleware
sys_sharemem.h
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2026 by Thun Lu. All rights reserved.
3  * Author: Thun Lu <thun.lu@zohomail.cn>
4  * Repo: https://github.com/thun-res/vlink
5  * _ __ __ _ __
6  * | | / / / / (_) ____ / /__
7  * | | / / / / / / / __ \ / //_/
8  * | |/ / / /___ / / / / / / / ,<
9  * |___/ /_____/ /_/ /_/ /_/ /_/|_|
10  *
11  * Licensed under the Apache License, Version 2.0 (the "License");
12  * you may not use this file except in compliance with the License.
13  * You may obtain a copy of the License at
14  *
15  * http://www.apache.org/licenses/LICENSE-2.0
16  *
17  * Unless required by applicable law or agreed to in writing, software
18  * distributed under the License is distributed on an "AS IS" BASIS,
19  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
20  * See the License for the specific language governing permissions and
21  * limitations under the License.
22  */
23 
24 /**
25  * @file sys_sharemem.h
26  * @brief Named cross-process shared-memory region.
27  *
28  * @details
29  * @c vlink::SysSharemem wraps the platform's shared-memory API: @c shm_open + @c mmap on
30  * POSIX targets, @c CreateFileMapping + @c MapViewOfFile on Windows. The region appears
31  * in the kernel namespace under a caller-chosen name and any process that knows the name
32  * can map it into its own address space.
33  *
34  * Memory layout exposed through @c data() and @c size():
35  *
36  * @verbatim
37  * +---------------------------------------------------+
38  * | byte 0 |
39  * | user payload (size = total bytes returned by |
40  * | size()) |
41  * | byte size-1 |
42  * +---------------------------------------------------+
43  * @endverbatim
44  *
45  * No internal header is reserved; the entire mapping is user payload. Place any
46  * synchronisation primitive (mutex, atomic counters, ring buffer indices) in the user
47  * region or in a companion @c SysSemaphore.
48  *
49  * Lifecycle states observed by the wrapper:
50  *
51  * | State | Entered by | @c is_attached() | @c data() |
52  * | ------------ | ----------------------- | ---------------- | --------------------- |
53  * | Detached | Construction, @c detach | @c false | @c nullptr |
54  * | Created | @c create() | @c true | Pointer to mapping |
55  * | Attached | @c attach() | @c true | Pointer to mapping |
56  *
57  * Access modes accepted by @c create() and @c attach():
58  *
59  * | Mode | POSIX flag | Effect |
60  * | ---------------- | ------------------- | ----------------------------------- |
61  * | @c kReadOnly | @c O_RDONLY | Maps with @c PROT_READ |
62  * | @c kReadWrite | @c O_RDWR | Maps with @c PROT_READ + PROT_WRITE |
63  *
64  * @note
65  * - POSIX names must begin with @c '/'; Windows accepts arbitrary non-empty strings.
66  * - The kernel zero-fills newly created regions on the supported POSIX/Windows backends.
67  * - Cross-process consistency requires external synchronisation.
68  *
69  * @par Example
70  * @code
71  * // Process A (creator)
72  * vlink::SysSharemem shm;
73  * shm.create("/vlink_frame", 1024 * 1024);
74  * auto* frame = static_cast<FrameHeader*>(shm.data());
75  * frame->seq = 0;
76  *
77  * // Process B (consumer)
78  * vlink::SysSharemem shm;
79  * shm.attach("/vlink_frame");
80  * const auto* frame = static_cast<const FrameHeader*>(shm.data());
81  * process_frame(*frame);
82  *
83  * shm.detach();
84  * @endcode
85  */
86 
87 #pragma once
88 
89 #include <cstdint>
90 #include <memory>
91 #include <string>
92 
93 #include "./macros.h"
94 
95 namespace vlink {
96 
97 /**
98  * @class SysSharemem
99  * @brief Named cross-process shared-memory region with read-only or read-write mappings.
100  *
101  * @details
102  * Manages one mapping at a time; call @c detach() before re-attaching to a different region.
103  */
105  public:
106  /**
107  * @enum Mode
108  * @brief Access mode applied to the mapping.
109  *
110  * @details
111  * Enumerator names mirror the POSIX @c O_RDONLY / @c O_RDWR open flags. On Windows the
112  * implementation translates these to the equivalent @c CreateFileMapping / @c MapViewOfFile
113  * page-protection constants; the observable behaviour is identical across platforms.
114  */
115  enum Mode : uint8_t {
116  kReadOnly = 0, ///< Read-only mapping; writes through @c data() are undefined.
117  kReadWrite = 1 ///< Read-write mapping (default).
118  };
119 
120  /**
121  * @brief Constructs a wrapper in the detached state.
122  */
124 
125  /**
126  * @brief Destructor. Invokes @c detach(false) when the wrapper is still attached.
127  */
129 
130  /**
131  * @brief Creates and maps a new shared-memory region of @p size bytes under @p name.
132  *
133  * @details
134  * Fails when a region with @p name already exists in the kernel namespace. The supported
135  * POSIX/Windows backends provide zero-initialised storage.
136  *
137  * @param name Kernel-name for the region. POSIX must begin with @c '/'.
138  * @param size Region size in bytes.
139  * @param mode Access mode for the mapping. Default: @c kReadWrite.
140  * @return @c true on success.
141  */
142  bool create(const std::string& name, size_t size, Mode mode = kReadWrite);
143 
144  /**
145  * @brief Attaches to an existing shared-memory region previously created with the same name.
146  *
147  * @param name Kernel-name of the region.
148  * @param mode Access mode for the mapping. Default: @c kReadWrite.
149  * @return @c true on success.
150  */
151  bool attach(const std::string& name, Mode mode = kReadWrite);
152 
153  /**
154  * @brief Unmaps the region and optionally unlinks the kernel name.
155  *
156  * @param force When @c true, POSIX backends call @c shm_unlink so the region is removed
157  * from the kernel namespace. Other processes that still hold mappings keep
158  * them. Windows merely closes the local mapping handle. Default: @c true.
159  * @return @c true on success.
160  */
161  bool detach(bool force = true);
162 
163  /**
164  * @brief Reports whether the wrapper currently owns a mapping.
165  *
166  * @return @c true after a successful @c create or @c attach.
167  */
168  [[nodiscard]] bool is_attached() const;
169 
170  /**
171  * @brief Returns a writable pointer to the start of the mapping.
172  *
173  * @return Mapping base pointer; @c nullptr when detached or in read-only mode.
174  */
175  [[nodiscard]] void* data();
176 
177  /**
178  * @brief Returns a read-only pointer to the start of the mapping.
179  *
180  * @return Const mapping base pointer; @c nullptr when detached.
181  */
182  [[nodiscard]] const void* data() const;
183 
184  /**
185  * @brief Returns the size of the mapping in bytes.
186  *
187  * @return Region size; @c 0 when detached.
188  */
189  [[nodiscard]] size_t size() const;
190 
191  private:
192  struct Impl;
193  std::unique_ptr<Impl> impl_;
194 
196 };
197 
198 } // namespace vlink
Cross-platform macros for visibility, branch hints, copy prevention, singletons and string helpers.
#define VLINK_EXPORT
Definition: macros.h:81
#define VLINK_DISALLOW_COPY_AND_ASSIGN(classname)
Deletes the copy constructor and copy-assignment operator of classname.
Definition: macros.h:174