/proc/self/cwd/source/common/init/target_impl.cc
Line | Count | Source (jump to first uncovered line) |
1 | | #include "source/common/init/target_impl.h" |
2 | | |
3 | | namespace Envoy { |
4 | | namespace Init { |
5 | | |
6 | | TargetHandleImpl::TargetHandleImpl(absl::string_view handle_name, absl::string_view name, |
7 | | std::weak_ptr<InternalInitializeFn> fn) |
8 | 8.65k | : handle_name_(handle_name), name_(name), fn_(std::move(fn)) {} |
9 | | |
10 | 5.50k | bool TargetHandleImpl::initialize(const Watcher& watcher) const { |
11 | 5.50k | auto locked_fn(fn_.lock()); |
12 | 5.50k | if (locked_fn) { |
13 | | // If we can "lock" a shared pointer to the target's callback function, call it |
14 | | // with a new handle to the ManagerImpl's watcher that was passed in. |
15 | 5.50k | ENVOY_LOG(debug, "{} initializing {}", handle_name_, name_); |
16 | 5.50k | (*locked_fn)(watcher.createHandle(name_)); |
17 | 5.50k | return true; |
18 | 5.50k | } else { |
19 | | // If not, the target was already destroyed. |
20 | 0 | ENVOY_LOG(debug, "{} can't initialize {} (unavailable)", handle_name_, name_); |
21 | 0 | return false; |
22 | 0 | } |
23 | 5.50k | } |
24 | | |
25 | 0 | absl::string_view TargetHandleImpl::name() const { return name_; } |
26 | | |
27 | | TargetImpl::TargetImpl(absl::string_view name, InitializeFn fn) |
28 | | : name_(fmt::format("target {}", name)), |
29 | 5.42k | fn_(std::make_shared<InternalInitializeFn>([this, fn](WatcherHandlePtr watcher_handle) { |
30 | 5.42k | watcher_handle_ = std::move(watcher_handle); |
31 | 5.42k | fn(); |
32 | 9.51k | })) {} |
33 | | |
34 | 9.51k | TargetImpl::~TargetImpl() { ENVOY_LOG(debug, "{} destroyed", name_); } |
35 | | |
36 | 8.57k | absl::string_view TargetImpl::name() const { return name_; } |
37 | | |
38 | 8.57k | TargetHandlePtr TargetImpl::createHandle(absl::string_view handle_name) const { |
39 | | // Note: can't use std::make_unique here because TargetHandleImpl ctor is private. |
40 | 8.57k | return TargetHandlePtr( |
41 | 8.57k | new TargetHandleImpl(handle_name, name_, std::weak_ptr<InternalInitializeFn>(fn_))); |
42 | 8.57k | } |
43 | | |
44 | 7.74k | bool TargetImpl::ready() { |
45 | 7.74k | if (watcher_handle_) { |
46 | | // If we have a handle for the ManagerImpl's watcher, signal it and then reset so it can't be |
47 | | // accidentally signaled again. |
48 | | // NOTE: We must move watcher_handle_ to a local to avoid the scenario in which as a result of |
49 | | // calling ready() this target is destroyed. This is possible in practice, for example when |
50 | | // a listener is deleted as a result of a failure in the context of the ready() call. |
51 | 4.05k | auto local_watcher_handle = std::move(watcher_handle_); |
52 | 4.05k | return local_watcher_handle->ready(); |
53 | 4.05k | } |
54 | 3.69k | return false; |
55 | 7.74k | } |
56 | | |
57 | | SharedTargetImpl::SharedTargetImpl(absl::string_view name, InitializeFn fn) |
58 | | : name_(fmt::format("shared target {}", name)), |
59 | 80 | fn_(std::make_shared<InternalInitializeFn>([this, fn](WatcherHandlePtr watcher_handle) { |
60 | 80 | if (initialized_) { |
61 | 12 | watcher_handle->ready(); |
62 | 68 | } else { |
63 | 68 | watcher_handles_.push_back(std::move(watcher_handle)); |
64 | 68 | std::call_once(once_flag_, fn); |
65 | 68 | } |
66 | 115 | })) {} |
67 | | |
68 | 115 | SharedTargetImpl::~SharedTargetImpl() { ENVOY_LOG(debug, "{} destroyed", name_); } |
69 | | |
70 | 80 | absl::string_view SharedTargetImpl::name() const { return name_; } |
71 | | |
72 | 80 | TargetHandlePtr SharedTargetImpl::createHandle(absl::string_view handle_name) const { |
73 | | // Note: can't use std::make_unique here because TargetHandleImpl ctor is private. |
74 | 80 | return TargetHandlePtr( |
75 | 80 | new TargetHandleImpl(handle_name, name_, std::weak_ptr<InternalInitializeFn>(fn_))); |
76 | 80 | } |
77 | | |
78 | 56 | bool SharedTargetImpl::ready() { |
79 | 56 | initialized_ = true; |
80 | | // NOTE: We must move watcher_handles_ to a local to avoid the scenario in which as a result of |
81 | | // calling ready() this target is destroyed. This is possible in practice, for example when |
82 | | // a listener is deleted as a result of a failure in the context of the ready() call. |
83 | 56 | auto local_watcher_handles = std::move(watcher_handles_); |
84 | 56 | bool all_notified = !local_watcher_handles.empty(); |
85 | 68 | for (auto& watcher_handle : local_watcher_handles) { |
86 | 68 | all_notified = watcher_handle->ready() && all_notified; |
87 | 68 | } |
88 | 56 | return all_notified; |
89 | 56 | } |
90 | | |
91 | | } // namespace Init |
92 | | } // namespace Envoy |