|
|
|
@ -187,9 +187,34 @@ struct stream_obj { |
|
|
|
|
|
|
|
|
|
/* Mutex to protect storage */ |
|
|
|
|
gpr_mu mu; |
|
|
|
|
|
|
|
|
|
/* Refcount object of the stream */ |
|
|
|
|
grpc_stream_refcount *refcount; |
|
|
|
|
}; |
|
|
|
|
typedef struct stream_obj stream_obj; |
|
|
|
|
|
|
|
|
|
#ifndef NDEBUG |
|
|
|
|
#define GRPC_CRONET_STREAM_REF(stream, reason) \ |
|
|
|
|
grpc_cronet_stream_ref((stream), (reason)) |
|
|
|
|
#define GRPC_CRONET_STREAM_UNREF(exec_ctx, stream, reason) \ |
|
|
|
|
grpc_cronet_stream_unref((exec_ctx), (stream), (reason)) |
|
|
|
|
void grpc_cronet_stream_ref(stream_obj *s, const char *reason) { |
|
|
|
|
grpc_stream_ref(s->refcount, reason); |
|
|
|
|
} |
|
|
|
|
void grpc_cronet_stream_unref(grpc_exec_ctx *exec_ctx, stream_obj *s, |
|
|
|
|
const char *reason) { |
|
|
|
|
grpc_stream_unref(exec_ctx, s->refcount, reason); |
|
|
|
|
} |
|
|
|
|
#else |
|
|
|
|
#define GRPC_CRONET_STREAM_REF(stream, reason) grpc_cronet_stream_ref((stream)) |
|
|
|
|
#define GRPC_CRONET_STREAM_UNREF(exec_ctx, stream, reason) \ |
|
|
|
|
grpc_cronet_stream_unref((exec_ctx), (stream)) |
|
|
|
|
void grpc_cronet_stream_ref(stream_obj *s) { grpc_stream_ref(s->refcount); } |
|
|
|
|
void grpc_cronet_stream_unref(grpc_exec_ctx *exec_ctx, stream_obj *s) { |
|
|
|
|
grpc_stream_unref(exec_ctx, s->refcount); |
|
|
|
|
} |
|
|
|
|
#endif |
|
|
|
|
|
|
|
|
|
static enum e_op_result execute_stream_op(grpc_exec_ctx *exec_ctx, |
|
|
|
|
struct op_and_state *oas); |
|
|
|
|
|
|
|
|
@ -346,13 +371,12 @@ static void remove_from_storage(struct stream_obj *s, |
|
|
|
|
This can get executed from the Cronet network thread via cronet callback |
|
|
|
|
or on the application supplied thread via the perform_stream_op function. |
|
|
|
|
*/ |
|
|
|
|
static void execute_from_storage(stream_obj *s) { |
|
|
|
|
grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT; |
|
|
|
|
static void execute_from_storage(grpc_exec_ctx *exec_ctx, stream_obj *s) { |
|
|
|
|
gpr_mu_lock(&s->mu); |
|
|
|
|
for (struct op_and_state *curr = s->storage.head; curr != NULL;) { |
|
|
|
|
CRONET_LOG(GPR_DEBUG, "calling op at %p. done = %d", curr, curr->done); |
|
|
|
|
GPR_ASSERT(curr->done == 0); |
|
|
|
|
enum e_op_result result = execute_stream_op(&exec_ctx, curr); |
|
|
|
|
enum e_op_result result = execute_stream_op(exec_ctx, curr); |
|
|
|
|
CRONET_LOG(GPR_DEBUG, "execute_stream_op[%p] returns %s", curr, |
|
|
|
|
op_result_string(result)); |
|
|
|
|
/* if this op is done, then remove it and free memory */ |
|
|
|
@ -369,7 +393,6 @@ static void execute_from_storage(stream_obj *s) { |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
gpr_mu_unlock(&s->mu); |
|
|
|
|
grpc_exec_ctx_finish(&exec_ctx); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
@ -377,6 +400,8 @@ static void execute_from_storage(stream_obj *s) { |
|
|
|
|
*/ |
|
|
|
|
static void on_failed(bidirectional_stream *stream, int net_error) { |
|
|
|
|
CRONET_LOG(GPR_DEBUG, "on_failed(%p, %d)", stream, net_error); |
|
|
|
|
grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT; |
|
|
|
|
|
|
|
|
|
stream_obj *s = (stream_obj *)stream->annotation; |
|
|
|
|
gpr_mu_lock(&s->mu); |
|
|
|
|
bidirectional_stream_destroy(s->cbs); |
|
|
|
@ -392,7 +417,9 @@ static void on_failed(bidirectional_stream *stream, int net_error) { |
|
|
|
|
} |
|
|
|
|
null_and_maybe_free_read_buffer(s); |
|
|
|
|
gpr_mu_unlock(&s->mu); |
|
|
|
|
execute_from_storage(s); |
|
|
|
|
execute_from_storage(&exec_ctx, s); |
|
|
|
|
GRPC_CRONET_STREAM_UNREF(&exec_ctx, s, "cronet transport"); |
|
|
|
|
grpc_exec_ctx_finish(&exec_ctx); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
@ -400,6 +427,8 @@ static void on_failed(bidirectional_stream *stream, int net_error) { |
|
|
|
|
*/ |
|
|
|
|
static void on_canceled(bidirectional_stream *stream) { |
|
|
|
|
CRONET_LOG(GPR_DEBUG, "on_canceled(%p)", stream); |
|
|
|
|
grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT; |
|
|
|
|
|
|
|
|
|
stream_obj *s = (stream_obj *)stream->annotation; |
|
|
|
|
gpr_mu_lock(&s->mu); |
|
|
|
|
bidirectional_stream_destroy(s->cbs); |
|
|
|
@ -415,7 +444,9 @@ static void on_canceled(bidirectional_stream *stream) { |
|
|
|
|
} |
|
|
|
|
null_and_maybe_free_read_buffer(s); |
|
|
|
|
gpr_mu_unlock(&s->mu); |
|
|
|
|
execute_from_storage(s); |
|
|
|
|
execute_from_storage(&exec_ctx, s); |
|
|
|
|
GRPC_CRONET_STREAM_UNREF(&exec_ctx, s, "cronet transport"); |
|
|
|
|
grpc_exec_ctx_finish(&exec_ctx); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
@ -423,6 +454,8 @@ static void on_canceled(bidirectional_stream *stream) { |
|
|
|
|
*/ |
|
|
|
|
static void on_succeeded(bidirectional_stream *stream) { |
|
|
|
|
CRONET_LOG(GPR_DEBUG, "on_succeeded(%p)", stream); |
|
|
|
|
grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT; |
|
|
|
|
|
|
|
|
|
stream_obj *s = (stream_obj *)stream->annotation; |
|
|
|
|
gpr_mu_lock(&s->mu); |
|
|
|
|
bidirectional_stream_destroy(s->cbs); |
|
|
|
@ -430,7 +463,9 @@ static void on_succeeded(bidirectional_stream *stream) { |
|
|
|
|
s->cbs = NULL; |
|
|
|
|
null_and_maybe_free_read_buffer(s); |
|
|
|
|
gpr_mu_unlock(&s->mu); |
|
|
|
|
execute_from_storage(s); |
|
|
|
|
execute_from_storage(&exec_ctx, s); |
|
|
|
|
GRPC_CRONET_STREAM_UNREF(&exec_ctx, s, "cronet transport"); |
|
|
|
|
grpc_exec_ctx_finish(&exec_ctx); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
@ -438,6 +473,7 @@ static void on_succeeded(bidirectional_stream *stream) { |
|
|
|
|
*/ |
|
|
|
|
static void on_stream_ready(bidirectional_stream *stream) { |
|
|
|
|
CRONET_LOG(GPR_DEBUG, "W: on_stream_ready(%p)", stream); |
|
|
|
|
grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT; |
|
|
|
|
stream_obj *s = (stream_obj *)stream->annotation; |
|
|
|
|
grpc_cronet_transport *t = (grpc_cronet_transport *)s->curr_ct; |
|
|
|
|
gpr_mu_lock(&s->mu); |
|
|
|
@ -457,7 +493,8 @@ static void on_stream_ready(bidirectional_stream *stream) { |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
gpr_mu_unlock(&s->mu); |
|
|
|
|
execute_from_storage(s); |
|
|
|
|
execute_from_storage(&exec_ctx, s); |
|
|
|
|
grpc_exec_ctx_finish(&exec_ctx); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
@ -513,14 +550,15 @@ static void on_response_headers_received( |
|
|
|
|
s->state.pending_read_from_cronet = true; |
|
|
|
|
} |
|
|
|
|
gpr_mu_unlock(&s->mu); |
|
|
|
|
execute_from_storage(&exec_ctx, s); |
|
|
|
|
grpc_exec_ctx_finish(&exec_ctx); |
|
|
|
|
execute_from_storage(s); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
Cronet callback |
|
|
|
|
*/ |
|
|
|
|
static void on_write_completed(bidirectional_stream *stream, const char *data) { |
|
|
|
|
grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT; |
|
|
|
|
stream_obj *s = (stream_obj *)stream->annotation; |
|
|
|
|
CRONET_LOG(GPR_DEBUG, "W: on_write_completed(%p, %s)", stream, data); |
|
|
|
|
gpr_mu_lock(&s->mu); |
|
|
|
@ -530,7 +568,8 @@ static void on_write_completed(bidirectional_stream *stream, const char *data) { |
|
|
|
|
} |
|
|
|
|
s->state.state_callback_received[OP_SEND_MESSAGE] = true; |
|
|
|
|
gpr_mu_unlock(&s->mu); |
|
|
|
|
execute_from_storage(s); |
|
|
|
|
execute_from_storage(&exec_ctx, s); |
|
|
|
|
grpc_exec_ctx_finish(&exec_ctx); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
@ -538,6 +577,7 @@ static void on_write_completed(bidirectional_stream *stream, const char *data) { |
|
|
|
|
*/ |
|
|
|
|
static void on_read_completed(bidirectional_stream *stream, char *data, |
|
|
|
|
int count) { |
|
|
|
|
grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT; |
|
|
|
|
stream_obj *s = (stream_obj *)stream->annotation; |
|
|
|
|
CRONET_LOG(GPR_DEBUG, "R: on_read_completed(%p, %p, %d)", stream, data, |
|
|
|
|
count); |
|
|
|
@ -563,14 +603,15 @@ static void on_read_completed(bidirectional_stream *stream, char *data, |
|
|
|
|
gpr_mu_unlock(&s->mu); |
|
|
|
|
} else { |
|
|
|
|
gpr_mu_unlock(&s->mu); |
|
|
|
|
execute_from_storage(s); |
|
|
|
|
execute_from_storage(&exec_ctx, s); |
|
|
|
|
} |
|
|
|
|
} else { |
|
|
|
|
null_and_maybe_free_read_buffer(s); |
|
|
|
|
s->state.rs.read_stream_closed = true; |
|
|
|
|
gpr_mu_unlock(&s->mu); |
|
|
|
|
execute_from_storage(s); |
|
|
|
|
execute_from_storage(&exec_ctx, s); |
|
|
|
|
} |
|
|
|
|
grpc_exec_ctx_finish(&exec_ctx); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
@ -625,12 +666,11 @@ static void on_response_trailers_received( |
|
|
|
|
s->state.state_op_done[OP_SEND_TRAILING_METADATA] = true; |
|
|
|
|
|
|
|
|
|
gpr_mu_unlock(&s->mu); |
|
|
|
|
grpc_exec_ctx_finish(&exec_ctx); |
|
|
|
|
} else { |
|
|
|
|
gpr_mu_unlock(&s->mu); |
|
|
|
|
grpc_exec_ctx_finish(&exec_ctx); |
|
|
|
|
execute_from_storage(s); |
|
|
|
|
execute_from_storage(&exec_ctx, s); |
|
|
|
|
} |
|
|
|
|
grpc_exec_ctx_finish(&exec_ctx); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
@ -1313,6 +1353,9 @@ static int init_stream(grpc_exec_ctx *exec_ctx, grpc_transport *gt, |
|
|
|
|
grpc_stream *gs, grpc_stream_refcount *refcount, |
|
|
|
|
const void *server_data, gpr_arena *arena) { |
|
|
|
|
stream_obj *s = (stream_obj *)gs; |
|
|
|
|
|
|
|
|
|
s->refcount = refcount; |
|
|
|
|
GRPC_CRONET_STREAM_REF(s, "cronet transport"); |
|
|
|
|
memset(&s->storage, 0, sizeof(s->storage)); |
|
|
|
|
s->storage.head = NULL; |
|
|
|
|
memset(&s->state, 0, sizeof(s->state)); |
|
|
|
@ -1370,7 +1413,7 @@ static void perform_stream_op(grpc_exec_ctx *exec_ctx, grpc_transport *gt, |
|
|
|
|
} |
|
|
|
|
stream_obj *s = (stream_obj *)gs; |
|
|
|
|
add_to_storage(s, op); |
|
|
|
|
execute_from_storage(s); |
|
|
|
|
execute_from_storage(exec_ctx, s); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static void destroy_stream(grpc_exec_ctx *exec_ctx, grpc_transport *gt, |
|
|
|
|