diff --git a/src/core/ext/filters/client_channel/resolver/fake/fake_resolver.c b/src/core/ext/filters/client_channel/resolver/fake/fake_resolver.c index a311334d1314a30bfe12331c14014fff5f838cf0..56ed4371a912166380b7c818efdd51569cdc1032 100644 --- a/src/core/ext/filters/client_channel/resolver/fake/fake_resolver.c +++ b/src/core/ext/filters/client_channel/resolver/fake/fake_resolver.c @@ -56,6 +56,10 @@ typedef struct { // grpc_resolver_next_locked()'s closure. grpc_channel_args* next_results; + // Results to use for the pretended re-resolution in + // fake_resolver_channel_saw_error_locked(). + grpc_channel_args* results_upon_error; + // pending next completion, or NULL grpc_closure* next_completion; // target result address for next completion @@ -65,6 +69,7 @@ typedef struct { static void fake_resolver_destroy(grpc_exec_ctx* exec_ctx, grpc_resolver* gr) { fake_resolver* r = (fake_resolver*)gr; grpc_channel_args_destroy(exec_ctx, r->next_results); + grpc_channel_args_destroy(exec_ctx, r->results_upon_error); grpc_channel_args_destroy(exec_ctx, r->channel_args); gpr_free(r); } @@ -87,15 +92,19 @@ static void fake_resolver_maybe_finish_next_locked(grpc_exec_ctx* exec_ctx, *r->target_result = grpc_channel_args_union(r->next_results, r->channel_args); grpc_channel_args_destroy(exec_ctx, r->next_results); + r->next_results = NULL; GRPC_CLOSURE_SCHED(exec_ctx, r->next_completion, GRPC_ERROR_NONE); r->next_completion = NULL; - r->next_results = NULL; } } static void fake_resolver_channel_saw_error_locked(grpc_exec_ctx* exec_ctx, grpc_resolver* resolver) { fake_resolver* r = (fake_resolver*)resolver; + if (r->next_results == NULL && r->results_upon_error != NULL) { + // Pretend we re-resolved. + r->next_results = grpc_channel_args_copy(r->results_upon_error); + } fake_resolver_maybe_finish_next_locked(exec_ctx, r); } @@ -151,6 +160,10 @@ static void set_response_cb(grpc_exec_ctx* exec_ctx, void* arg, grpc_channel_args_destroy(exec_ctx, r->next_results); } r->next_results = generator->next_response; + if (r->results_upon_error != NULL) { + grpc_channel_args_destroy(exec_ctx, r->results_upon_error); + } + r->results_upon_error = grpc_channel_args_copy(generator->next_response); fake_resolver_maybe_finish_next_locked(exec_ctx, r); }