|
@@ -141,7 +141,8 @@ void grpc_handshake_manager_destroy(grpc_exec_ctx* exec_ctx,
|
|
void grpc_handshake_manager_shutdown(grpc_exec_ctx* exec_ctx,
|
|
void grpc_handshake_manager_shutdown(grpc_exec_ctx* exec_ctx,
|
|
grpc_handshake_manager* mgr) {
|
|
grpc_handshake_manager* mgr) {
|
|
gpr_mu_lock(&mgr->mu);
|
|
gpr_mu_lock(&mgr->mu);
|
|
- if (mgr->index > 0) {
|
|
|
|
|
|
+ // Shutdown the handshaker that's currently in progress, if any.
|
|
|
|
+ if (mgr->index > 0 && mgr->index <= mgr->count) {
|
|
grpc_handshaker_shutdown(exec_ctx, mgr->handshakers[mgr->index - 1]);
|
|
grpc_handshaker_shutdown(exec_ctx, mgr->handshakers[mgr->index - 1]);
|
|
}
|
|
}
|
|
gpr_mu_unlock(&mgr->mu);
|
|
gpr_mu_unlock(&mgr->mu);
|
|
@@ -149,28 +150,27 @@ void grpc_handshake_manager_shutdown(grpc_exec_ctx* exec_ctx,
|
|
|
|
|
|
// Helper function to call either the next handshaker or the
|
|
// Helper function to call either the next handshaker or the
|
|
// on_handshake_done callback.
|
|
// on_handshake_done callback.
|
|
-static void call_next_handshaker_locked(grpc_exec_ctx* exec_ctx,
|
|
|
|
|
|
+// Returns true if we've scheduled the on_handshake_done callback.
|
|
|
|
+static bool call_next_handshaker_locked(grpc_exec_ctx* exec_ctx,
|
|
grpc_handshake_manager* mgr,
|
|
grpc_handshake_manager* mgr,
|
|
grpc_error* error) {
|
|
grpc_error* error) {
|
|
GPR_ASSERT(mgr->index <= mgr->count);
|
|
GPR_ASSERT(mgr->index <= mgr->count);
|
|
// If we got an error or we've finished the last handshaker, invoke
|
|
// If we got an error or we've finished the last handshaker, invoke
|
|
// the on_handshake_done callback. Otherwise, call the next handshaker.
|
|
// the on_handshake_done callback. Otherwise, call the next handshaker.
|
|
|
|
+ bool done = false;
|
|
if (error != GRPC_ERROR_NONE || mgr->index == mgr->count) {
|
|
if (error != GRPC_ERROR_NONE || mgr->index == mgr->count) {
|
|
// Cancel deadline timer, since we're invoking the on_handshake_done
|
|
// Cancel deadline timer, since we're invoking the on_handshake_done
|
|
// callback now.
|
|
// callback now.
|
|
grpc_timer_cancel(exec_ctx, &mgr->deadline_timer);
|
|
grpc_timer_cancel(exec_ctx, &mgr->deadline_timer);
|
|
grpc_exec_ctx_sched(exec_ctx, &mgr->on_handshake_done, error, NULL);
|
|
grpc_exec_ctx_sched(exec_ctx, &mgr->on_handshake_done, error, NULL);
|
|
- // Since we're invoking the final callback, we won't be coming back
|
|
|
|
- // to this function, so we can release our reference to the
|
|
|
|
- // handshake manager.
|
|
|
|
- grpc_handshake_manager_unref(exec_ctx, mgr);
|
|
|
|
- return;
|
|
|
|
|
|
+ done = true;
|
|
|
|
+ } else {
|
|
|
|
+ grpc_handshaker_do_handshake(exec_ctx, mgr->handshakers[mgr->index],
|
|
|
|
+ mgr->acceptor, &mgr->call_next_handshaker,
|
|
|
|
+ &mgr->args);
|
|
}
|
|
}
|
|
- // Call the next handshaker.
|
|
|
|
- grpc_handshaker_do_handshake(exec_ctx, mgr->handshakers[mgr->index],
|
|
|
|
- mgr->acceptor, &mgr->call_next_handshaker,
|
|
|
|
- &mgr->args);
|
|
|
|
++mgr->index;
|
|
++mgr->index;
|
|
|
|
+ return done;
|
|
}
|
|
}
|
|
|
|
|
|
// A function used as the handshaker-done callback when chaining
|
|
// A function used as the handshaker-done callback when chaining
|
|
@@ -179,8 +179,14 @@ static void call_next_handshaker(grpc_exec_ctx* exec_ctx, void* arg,
|
|
grpc_error* error) {
|
|
grpc_error* error) {
|
|
grpc_handshake_manager* mgr = arg;
|
|
grpc_handshake_manager* mgr = arg;
|
|
gpr_mu_lock(&mgr->mu);
|
|
gpr_mu_lock(&mgr->mu);
|
|
- call_next_handshaker_locked(exec_ctx, mgr, GRPC_ERROR_REF(error));
|
|
|
|
|
|
+ bool done = call_next_handshaker_locked(exec_ctx, mgr, GRPC_ERROR_REF(error));
|
|
gpr_mu_unlock(&mgr->mu);
|
|
gpr_mu_unlock(&mgr->mu);
|
|
|
|
+ // If we're invoked the final callback, we won't be coming back
|
|
|
|
+ // to this function, so we can release our reference to the
|
|
|
|
+ // handshake manager.
|
|
|
|
+ if (done) {
|
|
|
|
+ grpc_handshake_manager_unref(exec_ctx, mgr);
|
|
|
|
+ }
|
|
}
|
|
}
|
|
|
|
|
|
// Callback invoked when deadline is exceeded.
|
|
// Callback invoked when deadline is exceeded.
|
|
@@ -217,6 +223,9 @@ void grpc_handshake_manager_do_handshake(
|
|
on_timeout, mgr, gpr_now(GPR_CLOCK_MONOTONIC));
|
|
on_timeout, mgr, gpr_now(GPR_CLOCK_MONOTONIC));
|
|
// Start first handshaker, which also owns a ref.
|
|
// Start first handshaker, which also owns a ref.
|
|
gpr_ref(&mgr->refs);
|
|
gpr_ref(&mgr->refs);
|
|
- call_next_handshaker_locked(exec_ctx, mgr, GRPC_ERROR_NONE);
|
|
|
|
|
|
+ bool done = call_next_handshaker_locked(exec_ctx, mgr, GRPC_ERROR_NONE);
|
|
gpr_mu_unlock(&mgr->mu);
|
|
gpr_mu_unlock(&mgr->mu);
|
|
|
|
+ if (done) {
|
|
|
|
+ grpc_handshake_manager_unref(exec_ctx, mgr);
|
|
|
|
+ }
|
|
}
|
|
}
|