/proc/self/cwd/common/data.h
Line | Count | Source |
1 | | // Copyright 2024 Google LLC |
2 | | // |
3 | | // Licensed under the Apache License, Version 2.0 (the "License"); |
4 | | // you may not use this file except in compliance with the License. |
5 | | // You may obtain a copy of the License at |
6 | | // |
7 | | // https://www.apache.org/licenses/LICENSE-2.0 |
8 | | // |
9 | | // Unless required by applicable law or agreed to in writing, software |
10 | | // distributed under the License is distributed on an "AS IS" BASIS, |
11 | | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
12 | | // See the License for the specific language governing permissions and |
13 | | // limitations under the License. |
14 | | |
15 | | #ifndef THIRD_PARTY_CEL_CPP_COMMON_DATA_H_ |
16 | | #define THIRD_PARTY_CEL_CPP_COMMON_DATA_H_ |
17 | | |
18 | | #include <cstddef> |
19 | | #include <cstdint> |
20 | | |
21 | | #include "absl/base/nullability.h" |
22 | | #include "absl/log/absl_check.h" |
23 | | #include "common/internal/metadata.h" |
24 | | #include "google/protobuf/arena.h" |
25 | | |
26 | | namespace cel { |
27 | | |
28 | | class Data; |
29 | | template <typename T> |
30 | | struct Ownable; |
31 | | template <typename T> |
32 | | struct Borrowable; |
33 | | |
34 | | namespace common_internal { |
35 | | |
36 | | class ReferenceCount; |
37 | | |
38 | | void SetDataReferenceCount(const Data* absl_nonnull data, |
39 | | const ReferenceCount* absl_nonnull refcount); |
40 | | |
41 | | const ReferenceCount* absl_nullable GetDataReferenceCount( |
42 | | const Data* absl_nonnull data); |
43 | | |
44 | | } // namespace common_internal |
45 | | |
46 | | // `Data` is one of the base classes of objects that can be managed by |
47 | | // `MemoryManager`, the other is `google::protobuf::MessageLite`. |
48 | | class Data { |
49 | | public: |
50 | | Data(const Data&) = default; |
51 | | Data(Data&&) = default; |
52 | | ~Data() = default; |
53 | | Data& operator=(const Data&) = default; |
54 | | Data& operator=(Data&&) = default; |
55 | | |
56 | 0 | google::protobuf::Arena* absl_nullable GetArena() const { |
57 | 0 | return (owner_ & kOwnerBits) == kOwnerArenaBit |
58 | 0 | ? reinterpret_cast<google::protobuf::Arena*>(owner_ & kOwnerPointerMask) |
59 | 0 | : nullptr; |
60 | 0 | } |
61 | | |
62 | | protected: |
63 | | // At this point, the reference count has not been created. So we create it |
64 | | // unowned and set the reference count after. In theory we could create the |
65 | | // reference count ahead of time and then update it with the data it has to |
66 | | // delete, but that is a bit counter intuitive. Doing it this way is also |
67 | | // similar to how std::enable_shared_from_this works. |
68 | | Data() = default; |
69 | | |
70 | | Data(std::nullptr_t) = delete; |
71 | | |
72 | | explicit Data(google::protobuf::Arena* absl_nullable arena) |
73 | | : owner_(reinterpret_cast<uintptr_t>(arena) | |
74 | 0 | (arena != nullptr ? kOwnerArenaBit : kOwnerNone)) {} |
75 | | |
76 | | private: |
77 | | static constexpr uintptr_t kOwnerNone = common_internal::kMetadataOwnerNone; |
78 | | static constexpr uintptr_t kOwnerReferenceCountBit = |
79 | | common_internal::kMetadataOwnerReferenceCountBit; |
80 | | static constexpr uintptr_t kOwnerArenaBit = |
81 | | common_internal::kMetadataOwnerArenaBit; |
82 | | static constexpr uintptr_t kOwnerBits = common_internal::kMetadataOwnerBits; |
83 | | static constexpr uintptr_t kOwnerPointerMask = |
84 | | common_internal::kMetadataOwnerPointerMask; |
85 | | |
86 | | friend void common_internal::SetDataReferenceCount( |
87 | | const Data* absl_nonnull data, |
88 | | const common_internal::ReferenceCount* absl_nonnull refcount); |
89 | | friend const common_internal::ReferenceCount* absl_nullable |
90 | | common_internal::GetDataReferenceCount(const Data* absl_nonnull data); |
91 | | template <typename T> |
92 | | friend struct Ownable; |
93 | | template <typename T> |
94 | | friend struct Borrowable; |
95 | | |
96 | | mutable uintptr_t owner_ = kOwnerNone; |
97 | | }; |
98 | | |
99 | | namespace common_internal { |
100 | | |
101 | | inline void SetDataReferenceCount(const Data* absl_nonnull data, |
102 | 0 | const ReferenceCount* absl_nonnull refcount) { |
103 | 0 | ABSL_DCHECK_EQ(data->owner_, Data::kOwnerNone); |
104 | 0 | data->owner_ = |
105 | 0 | reinterpret_cast<uintptr_t>(refcount) | Data::kOwnerReferenceCountBit; |
106 | 0 | } |
107 | | |
108 | | inline const ReferenceCount* absl_nullable GetDataReferenceCount( |
109 | 0 | const Data* absl_nonnull data) { |
110 | 0 | return (data->owner_ & Data::kOwnerBits) == Data::kOwnerReferenceCountBit |
111 | 0 | ? reinterpret_cast<const ReferenceCount*>(data->owner_ & |
112 | 0 | Data::kOwnerPointerMask) |
113 | 0 | : nullptr; |
114 | 0 | } |
115 | | |
116 | | } // namespace common_internal |
117 | | |
118 | | } // namespace cel |
119 | | |
120 | | #endif // THIRD_PARTY_CEL_CPP_COMMON_DATA_H_ |