/Users/deen/code/yugabyte-db/src/yb/util/shared_mem.h
Line | Count | Source (jump to first uncovered line) |
1 | | // Copyright (c) YugaByte, Inc. |
2 | | // |
3 | | // Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except |
4 | | // in compliance with the License. You may obtain a copy of the License at |
5 | | // |
6 | | // http://www.apache.org/licenses/LICENSE-2.0 |
7 | | // |
8 | | // Unless required by applicable law or agreed to in writing, software distributed under the License |
9 | | // is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express |
10 | | // or implied. See the License for the specific language governing permissions and limitations |
11 | | // under the License. |
12 | | // |
13 | | |
14 | | #ifndef YB_UTIL_SHARED_MEM_H |
15 | | #define YB_UTIL_SHARED_MEM_H |
16 | | |
17 | | #include <sys/mman.h> |
18 | | |
19 | | #include <glog/logging.h> |
20 | | |
21 | | #include "yb/util/result.h" |
22 | | |
23 | | namespace yb { |
24 | | |
25 | | class SharedMemorySegment { |
26 | | public: |
27 | | // Represents a mode of access to shared memory. |
28 | | enum AccessMode { |
29 | | kReadOnly = PROT_READ, |
30 | | kReadWrite = PROT_READ | PROT_WRITE, |
31 | | }; |
32 | | |
33 | | // Creates a new anonymous shared memory segment with the given size. |
34 | | static Result<SharedMemorySegment> Create(size_t segment_size); |
35 | | |
36 | | // Opens an existing shared memory segment pointed to by a file descriptor. |
37 | | static Result<SharedMemorySegment> Open( |
38 | | int fd, |
39 | | AccessMode access_mode, |
40 | | size_t segment_size); |
41 | | |
42 | | SharedMemorySegment(SharedMemorySegment&& other); |
43 | | |
44 | | SharedMemorySegment(const SharedMemorySegment& other) = delete; |
45 | | |
46 | | ~SharedMemorySegment(); |
47 | | |
48 | | // Returns the address of the start of the shared memory segment. |
49 | | void* GetAddress() const; |
50 | | |
51 | | // Returns the file descriptor of the shared memory segment. |
52 | | int GetFd() const; |
53 | | |
54 | | private: |
55 | | SharedMemorySegment(void* base_address, int fd, size_t segment_size); |
56 | | |
57 | | // The address of the start of the shared memory segment. |
58 | | void* base_address_; |
59 | | |
60 | | // The file descriptor of the shared memory segment. |
61 | | int fd_; |
62 | | |
63 | | // The size, in bytes, of the shared memory segment. |
64 | | size_t segment_size_; |
65 | | }; |
66 | | |
67 | | // Utility wrapper for sharing object of specified type. |
68 | | template <class Object> |
69 | | class SharedMemoryObject { |
70 | | public: |
71 | | SharedMemoryObject(SharedMemoryObject&& rhs) |
72 | 52.9k | : segment_(std::move(rhs.segment_)), owned_(rhs.owned_) { |
73 | 52.9k | rhs.owned_ = false; |
74 | 52.9k | } |
75 | | |
76 | 59.3k | ~SharedMemoryObject() { |
77 | 59.3k | if (owned_) { |
78 | 263 | get()->~Object(); |
79 | 263 | } |
80 | 59.3k | } |
81 | | |
82 | | // See SharedMemorySegment::GetFd |
83 | 2.02k | int GetFd() const { |
84 | 2.02k | return segment_.GetFd(); |
85 | 2.02k | } |
86 | | |
87 | 498k | Object* get() const { |
88 | 498k | return static_cast<Object*>(segment_.GetAddress()); |
89 | 498k | } |
90 | | |
91 | | Object* operator->() const { |
92 | | return get(); |
93 | | } |
94 | | |
95 | 497k | Object& operator*() const { |
96 | 497k | return *get(); |
97 | 497k | } |
98 | | |
99 | | template <class... Args> |
100 | 17.3k | static Result<SharedMemoryObject> Create(Args&&... args) { |
101 | 17.3k | return SharedMemoryObject( |
102 | 17.3k | VERIFY_RESULT(SharedMemorySegment::Create(sizeof(Object))), |
103 | 17.3k | std::forward<Args>(args)...); |
104 | 17.3k | } |
105 | | |
106 | 6.09k | static Result<SharedMemoryObject> OpenReadOnly(int fd) { |
107 | 6.09k | return SharedMemoryObject(VERIFY_RESULT(SharedMemorySegment::Open( |
108 | 0 | fd, SharedMemorySegment::AccessMode::kReadOnly, sizeof(Object))), NotOwnedTag()); |
109 | 6.09k | } |
110 | | |
111 | | static Result<SharedMemoryObject> OpenReadWrite(int fd) { |
112 | | return SharedMemoryObject(VERIFY_RESULT(SharedMemorySegment::Open( |
113 | | fd, SharedMemorySegment::AccessMode::kReadWrite, sizeof(Object))), NotOwnedTag()); |
114 | | } |
115 | | |
116 | | private: |
117 | | template <class... Args> |
118 | | explicit SharedMemoryObject(SharedMemorySegment&& segment, Args&&... args) |
119 | 17.3k | : segment_(std::move(segment)), owned_(true) { |
120 | 17.3k | new (DCHECK_NOTNULL(segment_.GetAddress())) Object(std::forward<Args>(args)...); |
121 | 17.3k | } |
122 | | |
123 | | class NotOwnedTag {}; |
124 | | |
125 | | explicit SharedMemoryObject(SharedMemorySegment&& segment, NotOwnedTag tag) |
126 | 6.09k | : segment_(std::move(segment)), owned_(false) { |
127 | 6.09k | } |
128 | | |
129 | | SharedMemorySegment segment_; |
130 | | bool owned_; |
131 | | }; |
132 | | |
133 | | } // namespace yb |
134 | | |
135 | | #endif // YB_UTIL_SHARED_MEM_H |