|
|
|
@ -114,8 +114,17 @@ struct read_and_write_test_state { |
|
|
|
|
grpc_slice_buffer outgoing; |
|
|
|
|
grpc_closure done_read; |
|
|
|
|
grpc_closure done_write; |
|
|
|
|
grpc_closure read_scheduler; |
|
|
|
|
grpc_closure write_scheduler; |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
static void read_scheduler(void* data, grpc_error* /* error */) { |
|
|
|
|
struct read_and_write_test_state* state = |
|
|
|
|
static_cast<struct read_and_write_test_state*>(data); |
|
|
|
|
grpc_endpoint_read(state->read_ep, &state->incoming, &state->done_read, |
|
|
|
|
/*urgent=*/false); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static void read_and_write_test_read_handler(void* data, grpc_error* error) { |
|
|
|
|
struct read_and_write_test_state* state = |
|
|
|
|
static_cast<struct read_and_write_test_state*>(data); |
|
|
|
@ -129,11 +138,20 @@ static void read_and_write_test_read_handler(void* data, grpc_error* error) { |
|
|
|
|
GRPC_LOG_IF_ERROR("pollset_kick", grpc_pollset_kick(g_pollset, nullptr)); |
|
|
|
|
gpr_mu_unlock(g_mu); |
|
|
|
|
} else if (error == GRPC_ERROR_NONE) { |
|
|
|
|
grpc_endpoint_read(state->read_ep, &state->incoming, &state->done_read, |
|
|
|
|
/*urgent=*/false); |
|
|
|
|
/* We perform many reads one after another. If grpc_endpoint_read and the
|
|
|
|
|
* read_handler are both run inline, we might end up growing the stack |
|
|
|
|
* beyond the limit. Schedule the read on ExecCtx to avoid this. */ |
|
|
|
|
GRPC_CLOSURE_SCHED(&state->read_scheduler, GRPC_ERROR_NONE); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static void write_scheduler(void* data, grpc_error* /* error */) { |
|
|
|
|
struct read_and_write_test_state* state = |
|
|
|
|
static_cast<struct read_and_write_test_state*>(data); |
|
|
|
|
grpc_endpoint_write(state->write_ep, &state->outgoing, &state->done_write, |
|
|
|
|
nullptr); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static void read_and_write_test_write_handler(void* data, grpc_error* error) { |
|
|
|
|
struct read_and_write_test_state* state = |
|
|
|
|
static_cast<struct read_and_write_test_state*>(data); |
|
|
|
@ -151,8 +169,10 @@ static void read_and_write_test_write_handler(void* data, grpc_error* error) { |
|
|
|
|
&state->current_write_data); |
|
|
|
|
grpc_slice_buffer_reset_and_unref(&state->outgoing); |
|
|
|
|
grpc_slice_buffer_addn(&state->outgoing, slices, nslices); |
|
|
|
|
grpc_endpoint_write(state->write_ep, &state->outgoing, &state->done_write, |
|
|
|
|
nullptr); |
|
|
|
|
/* We perform many writes one after another. If grpc_endpoint_write and
|
|
|
|
|
* the write_handler are both run inline, we might end up growing the |
|
|
|
|
* stack beyond the limit. Schedule the write on ExecCtx to avoid this. */ |
|
|
|
|
GRPC_CLOSURE_SCHED(&state->write_scheduler, GRPC_ERROR_NONE); |
|
|
|
|
gpr_free(slices); |
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
@ -202,8 +222,12 @@ static void read_and_write_test(grpc_endpoint_test_config config, |
|
|
|
|
state.write_done = 0; |
|
|
|
|
state.current_read_data = 0; |
|
|
|
|
state.current_write_data = 0; |
|
|
|
|
GRPC_CLOSURE_INIT(&state.read_scheduler, read_scheduler, &state, |
|
|
|
|
grpc_schedule_on_exec_ctx); |
|
|
|
|
GRPC_CLOSURE_INIT(&state.done_read, read_and_write_test_read_handler, &state, |
|
|
|
|
grpc_schedule_on_exec_ctx); |
|
|
|
|
GRPC_CLOSURE_INIT(&state.write_scheduler, write_scheduler, &state, |
|
|
|
|
grpc_schedule_on_exec_ctx); |
|
|
|
|
GRPC_CLOSURE_INIT(&state.done_write, read_and_write_test_write_handler, |
|
|
|
|
&state, grpc_schedule_on_exec_ctx); |
|
|
|
|
grpc_slice_buffer_init(&state.outgoing); |
|
|
|
|