Line data Source code
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 314 : : handle_name_(handle_name), name_(name), fn_(std::move(fn)) {} 9 : 10 309 : bool TargetHandleImpl::initialize(const Watcher& watcher) const { 11 309 : auto locked_fn(fn_.lock()); 12 309 : 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 309 : ENVOY_LOG(debug, "{} initializing {}", handle_name_, name_); 16 309 : (*locked_fn)(watcher.createHandle(name_)); 17 309 : return true; 18 309 : } 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 309 : } 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 243 : fn_(std::make_shared<InternalInitializeFn>([this, fn](WatcherHandlePtr watcher_handle) { 30 243 : watcher_handle_ = std::move(watcher_handle); 31 243 : fn(); 32 302 : })) {} 33 : 34 302 : TargetImpl::~TargetImpl() { ENVOY_LOG(debug, "{} destroyed", name_); } 35 : 36 248 : absl::string_view TargetImpl::name() const { return name_; } 37 : 38 248 : TargetHandlePtr TargetImpl::createHandle(absl::string_view handle_name) const { 39 : // Note: can't use std::make_unique here because TargetHandleImpl ctor is private. 40 248 : return TargetHandlePtr( 41 248 : new TargetHandleImpl(handle_name, name_, std::weak_ptr<InternalInitializeFn>(fn_))); 42 248 : } 43 : 44 501 : bool TargetImpl::ready() { 45 501 : 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 238 : auto local_watcher_handle = std::move(watcher_handle_); 52 238 : return local_watcher_handle->ready(); 53 238 : } 54 263 : return false; 55 501 : } 56 : 57 : SharedTargetImpl::SharedTargetImpl(absl::string_view name, InitializeFn fn) 58 : : name_(fmt::format("shared target {}", name)), 59 66 : fn_(std::make_shared<InternalInitializeFn>([this, fn](WatcherHandlePtr watcher_handle) { 60 66 : if (initialized_) { 61 8 : watcher_handle->ready(); 62 58 : } else { 63 58 : watcher_handles_.push_back(std::move(watcher_handle)); 64 58 : std::call_once(once_flag_, fn); 65 58 : } 66 66 : })) {} 67 : 68 50 : SharedTargetImpl::~SharedTargetImpl() { ENVOY_LOG(debug, "{} destroyed", name_); } 69 : 70 66 : absl::string_view SharedTargetImpl::name() const { return name_; } 71 : 72 66 : TargetHandlePtr SharedTargetImpl::createHandle(absl::string_view handle_name) const { 73 : // Note: can't use std::make_unique here because TargetHandleImpl ctor is private. 74 66 : return TargetHandlePtr( 75 66 : new TargetHandleImpl(handle_name, name_, std::weak_ptr<InternalInitializeFn>(fn_))); 76 66 : } 77 : 78 50 : bool SharedTargetImpl::ready() { 79 50 : 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 50 : auto local_watcher_handles = std::move(watcher_handles_); 84 50 : bool all_notified = !local_watcher_handles.empty(); 85 58 : for (auto& watcher_handle : local_watcher_handles) { 86 58 : all_notified = watcher_handle->ready() && all_notified; 87 58 : } 88 50 : return all_notified; 89 50 : } 90 : 91 : } // namespace Init 92 : } // namespace Envoy