|
|
|
@ -230,7 +230,10 @@ struct transport { |
|
|
|
|
/* basic state management - what are we doing at the moment? */ |
|
|
|
|
gpr_uint8 reading; |
|
|
|
|
gpr_uint8 writing; |
|
|
|
|
gpr_uint8 calling_back; |
|
|
|
|
/** are we calling back (via cb) with a channel-level event */ |
|
|
|
|
gpr_uint8 calling_back_channel; |
|
|
|
|
/** are we calling back any grpc_transport_op completion events */ |
|
|
|
|
gpr_uint8 calling_back_ops; |
|
|
|
|
gpr_uint8 destroying; |
|
|
|
|
gpr_uint8 closed; |
|
|
|
|
error_state error_state; |
|
|
|
@ -357,7 +360,7 @@ static void push_setting(transport *t, grpc_chttp2_setting_id id, |
|
|
|
|
gpr_uint32 value); |
|
|
|
|
|
|
|
|
|
static int prepare_callbacks(transport *t); |
|
|
|
|
static void run_callbacks(transport *t, const grpc_transport_callbacks *cb); |
|
|
|
|
static void run_callbacks(transport *t); |
|
|
|
|
static void call_cb_closed(transport *t, const grpc_transport_callbacks *cb); |
|
|
|
|
|
|
|
|
|
static int prepare_write(transport *t); |
|
|
|
@ -565,7 +568,7 @@ static void init_transport(transport *t, grpc_transport_setup_callback setup, |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
gpr_mu_lock(&t->mu); |
|
|
|
|
t->calling_back = 1; |
|
|
|
|
t->calling_back_channel = 1; |
|
|
|
|
ref_transport(t); /* matches unref at end of this function */ |
|
|
|
|
gpr_mu_unlock(&t->mu); |
|
|
|
|
|
|
|
|
@ -574,7 +577,7 @@ static void init_transport(transport *t, grpc_transport_setup_callback setup, |
|
|
|
|
lock(t); |
|
|
|
|
t->cb = sr.callbacks; |
|
|
|
|
t->cb_user_data = sr.user_data; |
|
|
|
|
t->calling_back = 0; |
|
|
|
|
t->calling_back_channel = 0; |
|
|
|
|
if (t->destroying) gpr_cv_signal(&t->cv); |
|
|
|
|
unlock(t); |
|
|
|
|
|
|
|
|
@ -595,7 +598,7 @@ static void destroy_transport(grpc_transport *gt) { |
|
|
|
|
We need to be not writing as cancellation finalization may produce some |
|
|
|
|
callbacks that NEED to be made to close out some streams when t->writing |
|
|
|
|
becomes 0. */ |
|
|
|
|
while (t->calling_back || t->writing) { |
|
|
|
|
while (t->calling_back_channel || t->writing) { |
|
|
|
|
gpr_cv_wait(&t->cv, &t->mu, gpr_inf_future); |
|
|
|
|
} |
|
|
|
|
drop_connection(t); |
|
|
|
@ -830,28 +833,29 @@ static void unlock(transport *t) { |
|
|
|
|
finish_reads(t); |
|
|
|
|
|
|
|
|
|
/* gather any callbacks that need to be made */ |
|
|
|
|
if (!t->calling_back) { |
|
|
|
|
t->calling_back = perform_callbacks = prepare_callbacks(t); |
|
|
|
|
if (cb) { |
|
|
|
|
if (t->error_state == ERROR_STATE_SEEN && !t->writing) { |
|
|
|
|
call_closed = 1; |
|
|
|
|
t->calling_back = 1; |
|
|
|
|
t->cb = NULL; /* no more callbacks */ |
|
|
|
|
t->error_state = ERROR_STATE_NOTIFIED; |
|
|
|
|
} |
|
|
|
|
if (t->num_pending_goaways) { |
|
|
|
|
goaways = t->pending_goaways; |
|
|
|
|
num_goaways = t->num_pending_goaways; |
|
|
|
|
t->pending_goaways = NULL; |
|
|
|
|
t->num_pending_goaways = 0; |
|
|
|
|
t->cap_pending_goaways = 0; |
|
|
|
|
t->calling_back = 1; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
if (!t->calling_back_ops) { |
|
|
|
|
t->calling_back_ops = perform_callbacks = prepare_callbacks(t); |
|
|
|
|
if (perform_callbacks) ref_transport(t); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (perform_callbacks || call_closed || num_goaways) { |
|
|
|
|
ref_transport(t); |
|
|
|
|
if (!t->calling_back_channel && cb) { |
|
|
|
|
if (t->error_state == ERROR_STATE_SEEN && !t->writing) { |
|
|
|
|
call_closed = 1; |
|
|
|
|
t->calling_back_channel = 1; |
|
|
|
|
t->cb = NULL; /* no more callbacks */ |
|
|
|
|
t->error_state = ERROR_STATE_NOTIFIED; |
|
|
|
|
} |
|
|
|
|
if (t->num_pending_goaways) { |
|
|
|
|
goaways = t->pending_goaways; |
|
|
|
|
num_goaways = t->num_pending_goaways; |
|
|
|
|
t->pending_goaways = NULL; |
|
|
|
|
t->num_pending_goaways = 0; |
|
|
|
|
t->cap_pending_goaways = 0; |
|
|
|
|
t->calling_back_channel = 1; |
|
|
|
|
} |
|
|
|
|
if (call_closed || num_goaways) { |
|
|
|
|
ref_transport(t); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/* finally unlock */ |
|
|
|
@ -865,7 +869,11 @@ static void unlock(transport *t) { |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (perform_callbacks) { |
|
|
|
|
run_callbacks(t, cb); |
|
|
|
|
run_callbacks(t); |
|
|
|
|
lock(t); |
|
|
|
|
t->calling_back_ops = 0; |
|
|
|
|
unlock(t); |
|
|
|
|
unref_transport(t); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (call_closed) { |
|
|
|
@ -878,9 +886,9 @@ static void unlock(transport *t) { |
|
|
|
|
perform_write(t, ep); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (perform_callbacks || call_closed || num_goaways) { |
|
|
|
|
if (call_closed || num_goaways) { |
|
|
|
|
lock(t); |
|
|
|
|
t->calling_back = 0; |
|
|
|
|
t->calling_back_channel = 0; |
|
|
|
|
if (t->destroying) gpr_cv_signal(&t->cv); |
|
|
|
|
unlock(t); |
|
|
|
|
unref_transport(t); |
|
|
|
@ -2101,7 +2109,7 @@ static int prepare_callbacks(transport *t) { |
|
|
|
|
return t->executing_callbacks.count > 0; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static void run_callbacks(transport *t, const grpc_transport_callbacks *cb) { |
|
|
|
|
static void run_callbacks(transport *t) { |
|
|
|
|
size_t i; |
|
|
|
|
for (i = 0; i < t->executing_callbacks.count; i++) { |
|
|
|
|
op_closure c = t->executing_callbacks.callbacks[i]; |
|
|
|
|