/proc/self/cwd/runtime/internal/runtime_env.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_RUNTIME_INTERNAL_RUNTIME_ENV_H_ |
16 | | #define THIRD_PARTY_CEL_CPP_RUNTIME_INTERNAL_RUNTIME_ENV_H_ |
17 | | |
18 | | #include <atomic> |
19 | | #include <deque> |
20 | | #include <memory> |
21 | | #include <utility> |
22 | | |
23 | | #include "absl/base/attributes.h" |
24 | | #include "absl/base/nullability.h" |
25 | | #include "absl/base/thread_annotations.h" |
26 | | #include "absl/status/status.h" |
27 | | #include "absl/synchronization/mutex.h" |
28 | | #include "eval/public/cel_function_registry.h" |
29 | | #include "eval/public/cel_type_registry.h" |
30 | | #include "internal/well_known_types.h" |
31 | | #include "runtime/function_registry.h" |
32 | | #include "runtime/type_registry.h" |
33 | | #include "google/protobuf/descriptor.h" |
34 | | #include "google/protobuf/message.h" |
35 | | |
36 | | namespace cel::runtime_internal { |
37 | | |
38 | | // Shared state used by the runtime during creation, configuration, planning, |
39 | | // and evaluation. Passed around via `std::shared_ptr`. |
40 | | // |
41 | | // TODO(uncreated-issue/66): Make this a class. |
42 | | struct RuntimeEnv final { |
43 | | explicit RuntimeEnv(absl_nonnull std::shared_ptr<const google::protobuf::DescriptorPool> |
44 | | descriptor_pool, |
45 | | absl_nullable std::shared_ptr<google::protobuf::MessageFactory> |
46 | | message_factory = nullptr) |
47 | 14.5k | : descriptor_pool(std::move(descriptor_pool)), |
48 | 14.5k | message_factory(std::move(message_factory)), |
49 | 14.5k | legacy_type_registry(this->descriptor_pool.get(), |
50 | 14.5k | this->message_factory.get()), |
51 | 14.5k | type_registry(legacy_type_registry.InternalGetModernRegistry()), |
52 | 14.5k | function_registry(legacy_function_registry.InternalGetRegistry()) { |
53 | 14.5k | if (this->message_factory != nullptr) { |
54 | 14.5k | message_factory_ptr.store(this->message_factory.get(), |
55 | 14.5k | std::memory_order_seq_cst); |
56 | 14.5k | } |
57 | 14.5k | } |
58 | | |
59 | | // Not copyable or moveable. |
60 | | RuntimeEnv(const RuntimeEnv&) = delete; |
61 | | RuntimeEnv(RuntimeEnv&&) = delete; |
62 | | RuntimeEnv& operator=(const RuntimeEnv&) = delete; |
63 | | RuntimeEnv& operator=(RuntimeEnv&&) = delete; |
64 | | |
65 | | // Ideally the environment would already be initialized, but things are a bit |
66 | | // awkward. This should only be called once immediately after construction. |
67 | 14.5k | absl::Status Initialize() { |
68 | 14.5k | return well_known_types.Initialize(descriptor_pool.get()); |
69 | 14.5k | } |
70 | | |
71 | 0 | bool IsInitialized() const { return well_known_types.IsInitialized(); } |
72 | | |
73 | | ABSL_ATTRIBUTE_UNUSED |
74 | | const absl_nonnull std::shared_ptr<const google::protobuf::DescriptorPool> |
75 | | descriptor_pool; |
76 | | |
77 | | private: |
78 | | // These fields deal with a message factory that is lazily initialized as |
79 | | // needed. This might be called during the planning phase of an expression or |
80 | | // during evaluation. We want the ability to get the message factory when it |
81 | | // is already created to be cheap, so we use an atomic and a mutex for the |
82 | | // slow path. |
83 | | // |
84 | | // Do not access any of these fields directly, use member functions. |
85 | | mutable absl::Mutex message_factory_mutex; |
86 | | mutable absl_nullable std::shared_ptr<google::protobuf::MessageFactory> message_factory |
87 | | ABSL_GUARDED_BY(message_factory_mutex); |
88 | | // std::atomic<std::shared_ptr<?>> is not really a simple atomic, so we |
89 | | // avoid it. |
90 | | mutable std::atomic<google::protobuf::MessageFactory* absl_nullable> |
91 | | message_factory_ptr = nullptr; |
92 | | |
93 | | struct KeepAlives final { |
94 | 14.5k | KeepAlives() = default; |
95 | | |
96 | | ~KeepAlives(); |
97 | | |
98 | | // Not copyable or moveable. |
99 | | KeepAlives(const KeepAlives&) = delete; |
100 | | KeepAlives(KeepAlives&&) = delete; |
101 | | KeepAlives& operator=(const KeepAlives&) = delete; |
102 | | KeepAlives& operator=(KeepAlives&&) = delete; |
103 | | |
104 | | std::deque<std::shared_ptr<const void>> deque; |
105 | | }; |
106 | | |
107 | | KeepAlives keep_alives; |
108 | | |
109 | | public: |
110 | | // Because of legacy shenanigans, we use shared_ptr here. For legacy, this is |
111 | | // an unowned shared_ptr (a noop deleter) pointing to the modern equivalent |
112 | | // which is a member of the legacy variant. |
113 | | google::api::expr::runtime::CelTypeRegistry legacy_type_registry; |
114 | | google::api::expr::runtime::CelFunctionRegistry legacy_function_registry; |
115 | | TypeRegistry& type_registry; |
116 | | FunctionRegistry& function_registry; |
117 | | |
118 | | well_known_types::Reflection well_known_types; |
119 | | |
120 | | google::protobuf::MessageFactory* absl_nonnull MutableMessageFactory() const |
121 | | ABSL_ATTRIBUTE_LIFETIME_BOUND; |
122 | | |
123 | | // Not thread safe. Adds `keep_alive` to a list owned by this environment |
124 | | // and ensures it survives at least as long as this environment. Keep alives |
125 | | // are released in reverse order of their registration. This mimics normal |
126 | | // destructor rules of members. |
127 | | // |
128 | | // IMPORTANT: This should only be when building the runtime, and not after. |
129 | | void KeepAlive(std::shared_ptr<const void> keep_alive); |
130 | | }; |
131 | | |
132 | | } // namespace cel::runtime_internal |
133 | | |
134 | | #endif // THIRD_PARTY_CEL_CPP_RUNTIME_INTERNAL_RUNTIME_ENV_H_ |