From 241b838d689f8835a16d08f017ff8e03cd08c49e Mon Sep 17 00:00:00 2001 From: Hannah Shi Date: Fri, 16 Aug 2024 18:47:54 -0700 Subject: [PATCH] Sync c-core 1.66.0-pre5 --- gRPC-C++.podspec | 2 +- gRPC-Core.podspec | 2 +- gRPC-ProtoRPC.podspec | 2 +- gRPC-RxLibrary.podspec | 2 +- gRPC.podspec | 2 +- include/grpcpp/version_info.h | 4 +- .../handshaker/security/secure_endpoint.cc | 18 ++- src/core/lib/surface/call.cc | 7 + src/core/lib/surface/call.h | 19 +++ src/core/load_balancing/rls/rls.cc | 147 ++++++++++++------ .../!ProtoCompiler-gRPCCppPlugin.podspec | 2 +- .../!ProtoCompiler-gRPCPlugin.podspec | 2 +- src/objective-c/GRPCClient/version.h | 2 +- 13 files changed, 150 insertions(+), 61 deletions(-) diff --git a/gRPC-C++.podspec b/gRPC-C++.podspec index 248d6861e..c0f9396ff 100644 --- a/gRPC-C++.podspec +++ b/gRPC-C++.podspec @@ -22,7 +22,7 @@ Pod::Spec.new do |s| s.name = 'gRPC-C++' # TODO (mxyan): use version that match gRPC version when pod is stabilized - version = '1.66.0-pre3' + version = '1.66.0-pre5' s.version = version s.summary = 'gRPC C++ library' s.homepage = 'https://grpc.io' diff --git a/gRPC-Core.podspec b/gRPC-Core.podspec index b8aa45969..ea46a2448 100644 --- a/gRPC-Core.podspec +++ b/gRPC-Core.podspec @@ -21,7 +21,7 @@ Pod::Spec.new do |s| s.name = 'gRPC-Core' - version = '1.66.0-pre3' + version = '1.66.0-pre5' s.version = version s.summary = 'Core cross-platform gRPC library, written in C' s.homepage = 'https://grpc.io' diff --git a/gRPC-ProtoRPC.podspec b/gRPC-ProtoRPC.podspec index 7e7e3b1d1..7432e92c5 100644 --- a/gRPC-ProtoRPC.podspec +++ b/gRPC-ProtoRPC.podspec @@ -21,7 +21,7 @@ Pod::Spec.new do |s| s.name = 'gRPC-ProtoRPC' - version = '1.66.0-pre3' + version = '1.66.0-pre5' s.version = version s.summary = 'RPC library for Protocol Buffers, based on gRPC' s.homepage = 'https://grpc.io' diff --git a/gRPC-RxLibrary.podspec b/gRPC-RxLibrary.podspec index 31e3375a2..fcea5e482 100644 --- a/gRPC-RxLibrary.podspec +++ b/gRPC-RxLibrary.podspec @@ -21,7 +21,7 @@ Pod::Spec.new do |s| s.name = 'gRPC-RxLibrary' - version = '1.66.0-pre3' + version = '1.66.0-pre5' s.version = version s.summary = 'Reactive Extensions library for iOS/OSX.' s.homepage = 'https://grpc.io' diff --git a/gRPC.podspec b/gRPC.podspec index f38ebda54..a9c2e7475 100644 --- a/gRPC.podspec +++ b/gRPC.podspec @@ -20,7 +20,7 @@ Pod::Spec.new do |s| s.name = 'gRPC' - version = '1.66.0-pre3' + version = '1.66.0-pre5' s.version = version s.summary = 'gRPC client library for iOS/OSX' s.homepage = 'https://grpc.io' diff --git a/include/grpcpp/version_info.h b/include/grpcpp/version_info.h index e30d5008a..200c3bde5 100644 --- a/include/grpcpp/version_info.h +++ b/include/grpcpp/version_info.h @@ -21,7 +21,7 @@ #define GRPC_CPP_VERSION_MAJOR 1 #define GRPC_CPP_VERSION_MINOR 66 #define GRPC_CPP_VERSION_PATCH 0 -#define GRPC_CPP_VERSION_TAG "pre3" -#define GRPC_CPP_VERSION_STRING "1.66.0-pre3" +#define GRPC_CPP_VERSION_TAG "pre5" +#define GRPC_CPP_VERSION_STRING "1.66.0-pre5" #endif // GRPCPP_VERSION_INFO_H diff --git a/src/core/handshaker/security/secure_endpoint.cc b/src/core/handshaker/security/secure_endpoint.cc index 8210ff57d..c5e20ecdc 100644 --- a/src/core/handshaker/security/secure_endpoint.cc +++ b/src/core/handshaker/security/secure_endpoint.cc @@ -108,7 +108,6 @@ struct secure_endpoint : public grpc_endpoint { } ~secure_endpoint() { - memory_owner.Reset(); tsi_frame_protector_destroy(protector); tsi_zero_copy_grpc_protector_destroy(zero_copy_protector); grpc_slice_buffer_destroy(&source_buffer); @@ -254,6 +253,13 @@ static void on_read(void* user_data, grpc_error_handle error) { { grpc_core::MutexLock l(&ep->read_mu); + + // If we were shut down after this callback was scheduled with OK + // status but before it was invoked, we need to treat that as an error. + if (ep->wrapped_ep == nullptr && error.ok()) { + error = absl::CancelledError("secure endpoint shutdown"); + } + uint8_t* cur = GRPC_SLICE_START_PTR(ep->read_staging_buffer); uint8_t* end = GRPC_SLICE_END_PTR(ep->read_staging_buffer); @@ -380,9 +386,12 @@ static void flush_write_staging_buffer(secure_endpoint* ep, uint8_t** cur, static void on_write(void* user_data, grpc_error_handle error) { secure_endpoint* ep = static_cast(user_data); - grpc_core::ExecCtx::Run(DEBUG_LOCATION, std::exchange(ep->write_cb, nullptr), - std::move(error)); + grpc_closure* cb = ep->write_cb; + ep->write_cb = nullptr; SECURE_ENDPOINT_UNREF(ep, "write"); + grpc_core::EnsureRunInExecCtx([cb, error = std::move(error)]() { + grpc_core::Closure::Run(DEBUG_LOCATION, cb, error); + }); } static void endpoint_write(grpc_endpoint* secure_ep, grpc_slice_buffer* slices, @@ -503,7 +512,10 @@ static void endpoint_write(grpc_endpoint* secure_ep, grpc_slice_buffer* slices, static void endpoint_destroy(grpc_endpoint* secure_ep) { secure_endpoint* ep = reinterpret_cast(secure_ep); + ep->read_mu.Lock(); ep->wrapped_ep.reset(); + ep->memory_owner.Reset(); + ep->read_mu.Unlock(); SECURE_ENDPOINT_UNREF(ep, "destroy"); } diff --git a/src/core/lib/surface/call.cc b/src/core/lib/surface/call.cc index c2db94ee4..5740579ff 100644 --- a/src/core/lib/surface/call.cc +++ b/src/core/lib/surface/call.cc @@ -497,6 +497,13 @@ void grpc_call_tracer_set(grpc_call* call, return arena->SetContext(tracer); } +void grpc_call_tracer_set_and_manage(grpc_call* call, + grpc_core::ClientCallTracer* tracer) { + grpc_core::Arena* arena = grpc_call_get_arena(call); + arena->ManagedNew(tracer); + return arena->SetContext(tracer); +} + void* grpc_call_tracer_get(grpc_call* call) { grpc_core::Arena* arena = grpc_call_get_arena(call); auto* call_tracer = diff --git a/src/core/lib/surface/call.h b/src/core/lib/surface/call.h index 6da95634d..99ab4af5c 100644 --- a/src/core/lib/surface/call.h +++ b/src/core/lib/surface/call.h @@ -265,6 +265,16 @@ void grpc_call_log_batch(const char* file, int line, const grpc_op* ops, void grpc_call_tracer_set(grpc_call* call, grpc_core::ClientCallTracer* tracer); +// Sets call tracer on the call and manages its life by using the call's arena. +// When using this API, the tracer will be destroyed by grpc_call arena when +// grpc_call is about to be destroyed. The caller of this API SHOULD NOT +// manually destroy the tracer. This API is used by Python as a way of using +// Arena to manage the lifetime of the call tracer. Python needs this API +// because the tracer was created within a separate shared object library which +// doesn't have access to core functions like arena->ManagedNew<>. +void grpc_call_tracer_set_and_manage(grpc_call* call, + grpc_core::ClientCallTracer* tracer); + void* grpc_call_tracer_get(grpc_call* call); #define GRPC_CALL_LOG_BATCH(ops, nops) \ @@ -276,6 +286,15 @@ void* grpc_call_tracer_get(grpc_call* call); uint8_t grpc_call_is_client(grpc_call* call); +class ClientCallTracerWrapper { + public: + explicit ClientCallTracerWrapper(grpc_core::ClientCallTracer* tracer) + : tracer_(tracer) {} + + private: + std::unique_ptr tracer_; +}; + // Return an appropriate compression algorithm for the requested compression \a // level in the context of \a call. grpc_compression_algorithm grpc_call_compression_for_level( diff --git a/src/core/load_balancing/rls/rls.cc b/src/core/load_balancing/rls/rls.cc index 9b532bccf..5705a6c96 100644 --- a/src/core/load_balancing/rls/rls.cc +++ b/src/core/load_balancing/rls/rls.cc @@ -353,7 +353,8 @@ class RlsLb final : public LoadBalancingPolicy { // is called after releasing it. // // Both methods grab the data they need from the parent object. - void StartUpdate() ABSL_EXCLUSIVE_LOCKS_REQUIRED(&RlsLb::mu_); + void StartUpdate(OrphanablePtr* child_policy_to_delete) + ABSL_EXCLUSIVE_LOCKS_REQUIRED(&RlsLb::mu_); absl::Status MaybeFinishUpdate() ABSL_LOCKS_EXCLUDED(&RlsLb::mu_); void ExitIdleLocked() { @@ -397,14 +398,14 @@ class RlsLb final : public LoadBalancingPolicy { }; // Note: We are forced to disable lock analysis here because - // Orphan() is called by Unref() which is called by RefCountedPtr<>, which + // Orphaned() is called by Unref() which is called by RefCountedPtr<>, which // cannot have lock annotations for this particular caller. void Orphaned() override ABSL_NO_THREAD_SAFETY_ANALYSIS; RefCountedPtr lb_policy_; std::string target_; - bool is_shutdown_ = false; + bool is_shutdown_ = false; // Protected by WorkSerializer OrphanablePtr child_policy_; RefCountedPtr pending_config_; @@ -503,12 +504,25 @@ class RlsLb final : public LoadBalancingPolicy { // Returns a list of child policy wrappers on which FinishUpdate() // needs to be called after releasing the lock. std::vector OnRlsResponseLocked( - ResponseInfo response, std::unique_ptr backoff_state) + ResponseInfo response, std::unique_ptr backoff_state, + OrphanablePtr* child_policy_to_delete) ABSL_EXCLUSIVE_LOCKS_REQUIRED(&RlsLb::mu_); // Moves entry to the end of the LRU list. void MarkUsed() ABSL_EXCLUSIVE_LOCKS_REQUIRED(&RlsLb::mu_); + // Takes entries from child_policy_wrappers_ and appends them to the end + // of \a child_policy_wrappers. + void TakeChildPolicyWrappers( + std::vector>* child_policy_wrappers) + ABSL_EXCLUSIVE_LOCKS_REQUIRED(&RlsLb::mu_) { + child_policy_wrappers->insert( + child_policy_wrappers->end(), + std::make_move_iterator(child_policy_wrappers_.begin()), + std::make_move_iterator(child_policy_wrappers_.end())); + child_policy_wrappers_.clear(); + } + private: class BackoffTimer final : public InternallyRefCounted { public: @@ -566,19 +580,24 @@ class RlsLb final : public LoadBalancingPolicy { // the caller. Otherwise, the entry found is returned to the caller. The // entry returned to the user is considered recently used and its order in // the LRU list of the cache is updated. - Entry* FindOrInsert(const RequestKey& key) + Entry* FindOrInsert(const RequestKey& key, + std::vector>* + child_policy_wrappers_to_delete) ABSL_EXCLUSIVE_LOCKS_REQUIRED(&RlsLb::mu_); // Resizes the cache. If the new cache size is greater than the current size // of the cache, do nothing. Otherwise, evict the oldest entries that // exceed the new size limit of the cache. - void Resize(size_t bytes) ABSL_EXCLUSIVE_LOCKS_REQUIRED(&RlsLb::mu_); + void Resize(size_t bytes, std::vector>* + child_policy_wrappers_to_delete) + ABSL_EXCLUSIVE_LOCKS_REQUIRED(&RlsLb::mu_); // Resets backoff of all the cache entries. void ResetAllBackoff() ABSL_EXCLUSIVE_LOCKS_REQUIRED(&RlsLb::mu_); // Shutdown the cache; clean-up and orphan all the stored cache entries. - void Shutdown() ABSL_EXCLUSIVE_LOCKS_REQUIRED(&RlsLb::mu_); + GRPC_MUST_USE_RESULT std::vector> + Shutdown() ABSL_EXCLUSIVE_LOCKS_REQUIRED(&RlsLb::mu_); void ReportMetricsLocked(CallbackMetricReporter& reporter) ABSL_EXCLUSIVE_LOCKS_REQUIRED(&RlsLb::mu_); @@ -594,7 +613,9 @@ class RlsLb final : public LoadBalancingPolicy { // Evicts oversized cache elements when the current size is greater than // the specified limit. - void MaybeShrinkSize(size_t bytes) + void MaybeShrinkSize(size_t bytes, + std::vector>* + child_policy_wrappers_to_delete) ABSL_EXCLUSIVE_LOCKS_REQUIRED(&RlsLb::mu_); RlsLb* lb_policy_; @@ -859,7 +880,8 @@ absl::optional InsertOrUpdateChildPolicyField(const std::string& field, return Json::FromArray(std::move(array)); } -void RlsLb::ChildPolicyWrapper::StartUpdate() { +void RlsLb::ChildPolicyWrapper::StartUpdate( + OrphanablePtr* child_policy_to_delete) { ValidationErrors errors; auto child_policy_config = InsertOrUpdateChildPolicyField( lb_policy_->config_->child_policy_config_target_field_name(), target_, @@ -884,7 +906,7 @@ void RlsLb::ChildPolicyWrapper::StartUpdate() { pending_config_.reset(); picker_ = MakeRefCounted( absl::UnavailableError(config.status().message())); - child_policy_.reset(); + *child_policy_to_delete = std::move(child_policy_); } else { pending_config_ = std::move(*config); } @@ -939,9 +961,9 @@ void RlsLb::ChildPolicyWrapper::ChildPolicyHelper::UpdateState( << ": UpdateState(state=" << ConnectivityStateName(state) << ", status=" << status << ", picker=" << picker.get() << ")"; } + if (wrapper_->is_shutdown_) return; { MutexLock lock(&wrapper_->lb_policy_->mu_); - if (wrapper_->is_shutdown_) return; // TODO(roth): It looks like this ignores subsequent TF updates that // might change the status used to fail picks, which seems wrong. if (wrapper_->connectivity_state_ == GRPC_CHANNEL_TRANSIENT_FAILURE && @@ -951,7 +973,8 @@ void RlsLb::ChildPolicyWrapper::ChildPolicyHelper::UpdateState( wrapper_->connectivity_state_ = state; DCHECK(picker != nullptr); if (picker != nullptr) { - wrapper_->picker_ = std::move(picker); + // We want to unref the picker after we release the lock. + wrapper_->picker_.swap(picker); } } wrapper_->lb_policy_->UpdatePickerLocked(); @@ -1204,19 +1227,19 @@ RlsLb::Cache::Entry::Entry(RefCountedPtr lb_policy, lb_policy_->cache_.lru_list_.end(), key)) {} void RlsLb::Cache::Entry::Orphan() { - if (GRPC_TRACE_FLAG_ENABLED(rls_lb)) { - LOG(INFO) << "[rlslb " << lb_policy_.get() << "] cache entry=" << this - << " " << lru_iterator_->ToString() << ": cache entry evicted"; - } + // We should be holding RlsLB::mu_. + GRPC_TRACE_LOG(rls_lb, INFO) + << "[rlslb " << lb_policy_.get() << "] cache entry=" << this << " " + << lru_iterator_->ToString() << ": cache entry evicted"; is_shutdown_ = true; lb_policy_->cache_.lru_list_.erase(lru_iterator_); lru_iterator_ = lb_policy_->cache_.lru_list_.end(); // Just in case. + CHECK(child_policy_wrappers_.empty()); backoff_state_.reset(); if (backoff_timer_ != nullptr) { backoff_timer_.reset(); lb_policy_->UpdatePickerAsync(); } - child_policy_wrappers_.clear(); Unref(DEBUG_LOCATION, "Orphan"); } @@ -1295,7 +1318,8 @@ void RlsLb::Cache::Entry::MarkUsed() { std::vector RlsLb::Cache::Entry::OnRlsResponseLocked( - ResponseInfo response, std::unique_ptr backoff_state) { + ResponseInfo response, std::unique_ptr backoff_state, + OrphanablePtr* child_policy_to_delete) { // Move the entry to the end of the LRU list. MarkUsed(); // If the request failed, store the failed status and update the @@ -1356,7 +1380,7 @@ RlsLb::Cache::Entry::OnRlsResponseLocked( if (it == lb_policy_->child_policy_map_.end()) { auto new_child = MakeRefCounted( lb_policy_.Ref(DEBUG_LOCATION, "ChildPolicyWrapper"), target); - new_child->StartUpdate(); + new_child->StartUpdate(child_policy_to_delete); child_policies_to_finish_update.push_back(new_child.get()); new_child_policy_wrappers.emplace_back(std::move(new_child)); } else { @@ -1393,12 +1417,15 @@ RlsLb::Cache::Entry* RlsLb::Cache::Find(const RequestKey& key) { return it->second.get(); } -RlsLb::Cache::Entry* RlsLb::Cache::FindOrInsert(const RequestKey& key) { +RlsLb::Cache::Entry* RlsLb::Cache::FindOrInsert( + const RequestKey& key, std::vector>* + child_policy_wrappers_to_delete) { auto it = map_.find(key); // If not found, create new entry. if (it == map_.end()) { size_t entry_size = EntrySizeForKey(key); - MaybeShrinkSize(size_limit_ - std::min(size_limit_, entry_size)); + MaybeShrinkSize(size_limit_ - std::min(size_limit_, entry_size), + child_policy_wrappers_to_delete); Entry* entry = new Entry( lb_policy_->RefAsSubclass(DEBUG_LOCATION, "CacheEntry"), key); map_.emplace(key, OrphanablePtr(entry)); @@ -1418,13 +1445,13 @@ RlsLb::Cache::Entry* RlsLb::Cache::FindOrInsert(const RequestKey& key) { return it->second.get(); } -void RlsLb::Cache::Resize(size_t bytes) { - if (GRPC_TRACE_FLAG_ENABLED(rls_lb)) { - LOG(INFO) << "[rlslb " << lb_policy_ << "] resizing cache to " << bytes - << " bytes"; - } +void RlsLb::Cache::Resize(size_t bytes, + std::vector>* + child_policy_wrappers_to_delete) { + GRPC_TRACE_LOG(rls_lb, INFO) + << "[rlslb " << lb_policy_ << "] resizing cache to " << bytes << " bytes"; size_limit_ = bytes; - MaybeShrinkSize(size_limit_); + MaybeShrinkSize(size_limit_, child_policy_wrappers_to_delete); } void RlsLb::Cache::ResetAllBackoff() { @@ -1434,7 +1461,12 @@ void RlsLb::Cache::ResetAllBackoff() { lb_policy_->UpdatePickerAsync(); } -void RlsLb::Cache::Shutdown() { +std::vector> RlsLb::Cache::Shutdown() { + std::vector> + child_policy_wrappers_to_delete; + for (auto& entry : map_) { + entry.second->TakeChildPolicyWrappers(&child_policy_wrappers_to_delete); + } map_.clear(); lru_list_.clear(); if (cleanup_timer_handle_.has_value() && @@ -1445,6 +1477,7 @@ void RlsLb::Cache::Shutdown() { } } cleanup_timer_handle_.reset(); + return child_policy_wrappers_to_delete; } void RlsLb::Cache::ReportMetricsLocked(CallbackMetricReporter& reporter) { @@ -1478,15 +1511,17 @@ void RlsLb::Cache::StartCleanupTimer() { } void RlsLb::Cache::OnCleanupTimer() { - if (GRPC_TRACE_FLAG_ENABLED(rls_lb)) { - LOG(INFO) << "[rlslb " << lb_policy_ << "] cache cleanup timer fired"; - } + GRPC_TRACE_LOG(rls_lb, INFO) + << "[rlslb " << lb_policy_ << "] cache cleanup timer fired"; + std::vector> + child_policy_wrappers_to_delete; MutexLock lock(&lb_policy_->mu_); if (!cleanup_timer_handle_.has_value()) return; if (lb_policy_->is_shutdown_) return; for (auto it = map_.begin(); it != map_.end();) { if (GPR_UNLIKELY(it->second->ShouldRemove() && it->second->CanEvict())) { size_ -= it->second->Size(); + it->second->TakeChildPolicyWrappers(&child_policy_wrappers_to_delete); it = map_.erase(it); } else { ++it; @@ -1500,7 +1535,9 @@ size_t RlsLb::Cache::EntrySizeForKey(const RequestKey& key) { return (key.Size() * 2) + sizeof(Entry); } -void RlsLb::Cache::MaybeShrinkSize(size_t bytes) { +void RlsLb::Cache::MaybeShrinkSize( + size_t bytes, std::vector>* + child_policy_wrappers_to_delete) { while (size_ > bytes) { auto lru_it = lru_list_.begin(); if (GPR_UNLIKELY(lru_it == lru_list_.end())) break; @@ -1512,6 +1549,7 @@ void RlsLb::Cache::MaybeShrinkSize(size_t bytes) { << map_it->second.get() << " " << lru_it->ToString(); } size_ -= map_it->second->Size(); + map_it->second->TakeChildPolicyWrappers(child_policy_wrappers_to_delete); map_.erase(map_it); } if (GRPC_TRACE_FLAG_ENABLED(rls_lb)) { @@ -1841,13 +1879,18 @@ void RlsLb::RlsRequest::OnRlsCallCompleteLocked(grpc_error_handle error) { << ": response info: " << response.ToString(); } std::vector child_policies_to_finish_update; + std::vector> + child_policy_wrappers_to_delete; + OrphanablePtr child_policy_to_delete; { MutexLock lock(&lb_policy_->mu_); if (lb_policy_->is_shutdown_) return; rls_channel_->ReportResponseLocked(response.status.ok()); - Cache::Entry* cache_entry = lb_policy_->cache_.FindOrInsert(key_); + Cache::Entry* cache_entry = + lb_policy_->cache_.FindOrInsert(key_, &child_policy_wrappers_to_delete); child_policies_to_finish_update = cache_entry->OnRlsResponseLocked( - std::move(response), std::move(backoff_state_)); + std::move(response), std::move(backoff_state_), + &child_policy_to_delete); lb_policy_->request_map_.erase(key_); } // Now that we've released the lock, finish the update on any newly @@ -2041,6 +2084,9 @@ absl::Status RlsLb::UpdateLocked(UpdateArgs args) { } } // Now grab the lock to swap out the state it guards. + std::vector> + child_policy_wrappers_to_delete; + OrphanablePtr child_policy_to_delete; { MutexLock lock(&mu_); // Swap out RLS channel if needed. @@ -2052,7 +2098,8 @@ absl::Status RlsLb::UpdateLocked(UpdateArgs args) { // Resize cache if needed. if (old_config == nullptr || config_->cache_size_bytes() != old_config->cache_size_bytes()) { - cache_.Resize(static_cast(config_->cache_size_bytes())); + cache_.Resize(static_cast(config_->cache_size_bytes()), + &child_policy_wrappers_to_delete); } // Start update of child policies if needed. if (update_child_policies) { @@ -2060,14 +2107,12 @@ absl::Status RlsLb::UpdateLocked(UpdateArgs args) { LOG(INFO) << "[rlslb " << this << "] starting child policy updates"; } for (auto& p : child_policy_map_) { - p.second->StartUpdate(); + p.second->StartUpdate(&child_policy_to_delete); } } else if (created_default_child) { - if (GRPC_TRACE_FLAG_ENABLED(rls_lb)) { - LOG(INFO) << "[rlslb " << this - << "] starting default child policy update"; - } - default_child_policy_->StartUpdate(); + GRPC_TRACE_LOG(rls_lb, INFO) + << "[rlslb " << this << "] starting default child policy update"; + default_child_policy_->StartUpdate(&child_policy_to_delete); } } // Now that we've released the lock, finish update of child policies. @@ -2133,14 +2178,20 @@ void RlsLb::ShutdownLocked() { LOG(INFO) << "[rlslb " << this << "] policy shutdown"; } registered_metric_callback_.reset(); - MutexLock lock(&mu_); - is_shutdown_ = true; - config_.reset(DEBUG_LOCATION, "ShutdownLocked"); + RefCountedPtr child_policy_to_delete; + std::vector> + child_policy_wrappers_to_delete; + OrphanablePtr rls_channel_to_delete; + { + MutexLock lock(&mu_); + is_shutdown_ = true; + config_.reset(DEBUG_LOCATION, "ShutdownLocked"); + child_policy_wrappers_to_delete = cache_.Shutdown(); + request_map_.clear(); + rls_channel_to_delete = std::move(rls_channel_); + child_policy_to_delete = std::move(default_child_policy_); + } channel_args_ = ChannelArgs(); - cache_.Shutdown(); - request_map_.clear(); - rls_channel_.reset(); - default_child_policy_.reset(); } void RlsLb::UpdatePickerAsync() { diff --git a/src/objective-c/!ProtoCompiler-gRPCCppPlugin.podspec b/src/objective-c/!ProtoCompiler-gRPCCppPlugin.podspec index 5d66399d8..4ebcab796 100644 --- a/src/objective-c/!ProtoCompiler-gRPCCppPlugin.podspec +++ b/src/objective-c/!ProtoCompiler-gRPCCppPlugin.podspec @@ -42,7 +42,7 @@ Pod::Spec.new do |s| # exclamation mark ensures that other "regular" pods will be able to find it as it'll be installed # before them. s.name = '!ProtoCompiler-gRPCCppPlugin' - v = '1.66.0-pre3' + v = '1.66.0-pre5' s.version = v s.summary = 'The gRPC ProtoC plugin generates C++ files from .proto services.' s.description = <<-DESC diff --git a/src/objective-c/!ProtoCompiler-gRPCPlugin.podspec b/src/objective-c/!ProtoCompiler-gRPCPlugin.podspec index 43a49b350..4a591d85f 100644 --- a/src/objective-c/!ProtoCompiler-gRPCPlugin.podspec +++ b/src/objective-c/!ProtoCompiler-gRPCPlugin.podspec @@ -42,7 +42,7 @@ Pod::Spec.new do |s| # exclamation mark ensures that other "regular" pods will be able to find it as it'll be installed # before them. s.name = '!ProtoCompiler-gRPCPlugin' - v = '1.66.0-pre3' + v = '1.66.0-pre5' s.version = v s.summary = 'The gRPC ProtoC plugin generates Objective-C files from .proto services.' s.description = <<-DESC diff --git a/src/objective-c/GRPCClient/version.h b/src/objective-c/GRPCClient/version.h index 640b4c4f3..2e44d068d 100644 --- a/src/objective-c/GRPCClient/version.h +++ b/src/objective-c/GRPCClient/version.h @@ -22,4 +22,4 @@ // instead. This file can be regenerated from the template by running // `tools/buildgen/generate_projects.sh`. -#define GRPC_OBJC_VERSION_STRING @"1.66.0-pre3" +#define GRPC_OBJC_VERSION_STRING @"1.66.0-pre5"