YugabyteDB (2.13.1.0-b60, 21121d69985fbf76aa6958d8f04a9bfa936293b5)

Coverage Report

Created: 2022-03-22 16:43

/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