Coverage Report

Created: 2024-09-19 09:45

/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