Propagate grpc_millis further

pull/11888/head
Craig Tiller 7 years ago
parent 2e37d001a3
commit 89c1428a60
  1. 36
      src/core/ext/filters/client_channel/client_channel.c
  2. 8
      src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.c
  3. 2
      src/core/ext/filters/client_channel/subchannel.h
  4. 16
      src/core/ext/filters/deadline/deadline_filter.c
  5. 4
      src/core/ext/filters/deadline/deadline_filter.h
  6. 27
      src/core/ext/transport/chttp2/transport/chttp2_transport.c
  7. 10
      src/core/ext/transport/chttp2/transport/hpack_encoder.c
  8. 4
      src/core/ext/transport/chttp2/transport/incoming_metadata.c
  9. 2
      src/core/ext/transport/chttp2/transport/incoming_metadata.h
  10. 2
      src/core/ext/transport/chttp2/transport/internal.h
  11. 11
      src/core/ext/transport/chttp2/transport/parsing.c
  12. 16
      src/core/ext/transport/inproc/inproc_transport.c
  13. 2
      src/core/lib/channel/channel_stack.h
  14. 54
      src/core/lib/surface/call.c
  15. 2
      src/core/lib/surface/call.h
  16. 9
      src/core/lib/surface/channel.c
  17. 2
      src/core/lib/surface/channel.h
  18. 2
      src/core/lib/surface/lame_client.cc
  19. 16
      src/core/lib/surface/server.c
  20. 9
      src/core/lib/transport/error_utils.c
  21. 6
      src/core/lib/transport/error_utils.h
  22. 6
      src/core/lib/transport/metadata_batch.c
  23. 4
      src/core/lib/transport/metadata_batch.h
  24. 7
      src/core/lib/transport/status_conversion.c
  25. 6
      src/core/lib/transport/status_conversion.h
  26. 73
      src/core/lib/transport/timeout_encoding.c
  27. 5
      src/core/lib/transport/timeout_encoding.h
  28. 5
      src/core/lib/transport/transport_op_string.c
  29. 2
      test/core/channel/channel_stack_test.c
  30. 13
      test/core/transport/status_conversion_test.c
  31. 105
      test/core/transport/timeout_encoding_test.c
  32. 2
      test/cpp/microbenchmarks/bm_call_create.cc
  33. 6
      test/cpp/microbenchmarks/bm_chttp2_transport.cc
  34. 6
      test/cpp/microbenchmarks/bm_cq_multiple_threads.cc
  35. 42
      test/cpp/microbenchmarks/bm_error.cc
  36. 9
      test/cpp/microbenchmarks/bm_pollset.cc

@ -68,7 +68,7 @@ typedef enum {
typedef struct {
gpr_refcount refs;
gpr_timespec timeout;
grpc_millis timeout;
wait_for_ready_value wait_for_ready;
} method_parameters;
@ -98,17 +98,18 @@ static bool parse_wait_for_ready(grpc_json *field,
return true;
}
static bool parse_timeout(grpc_json *field, gpr_timespec *timeout) {
static bool parse_timeout(grpc_json *field, grpc_millis *timeout) {
if (field->type != GRPC_JSON_STRING) return false;
size_t len = strlen(field->value);
if (field->value[len - 1] != 's') return false;
char *buf = gpr_strdup(field->value);
buf[len - 1] = '\0'; // Remove trailing 's'.
char *decimal_point = strchr(buf, '.');
int nanos = 0;
if (decimal_point != NULL) {
*decimal_point = '\0';
timeout->tv_nsec = gpr_parse_nonnegative_int(decimal_point + 1);
if (timeout->tv_nsec == -1) {
nanos = gpr_parse_nonnegative_int(decimal_point + 1);
if (nanos == -1) {
gpr_free(buf);
return false;
}
@ -127,24 +128,25 @@ static bool parse_timeout(grpc_json *field, gpr_timespec *timeout) {
gpr_free(buf);
return false;
}
timeout->tv_nsec *= multiplier;
nanos *= multiplier;
}
timeout->tv_sec = gpr_parse_nonnegative_int(buf);
int seconds = gpr_parse_nonnegative_int(buf);
gpr_free(buf);
if (timeout->tv_sec == -1) return false;
if (seconds == -1) return false;
*timeout = seconds * GPR_MS_PER_SEC + nanos / GPR_NS_PER_MS;
return true;
}
static void *method_parameters_create_from_json(const grpc_json *json) {
wait_for_ready_value wait_for_ready = WAIT_FOR_READY_UNSET;
gpr_timespec timeout = {0, 0, GPR_TIMESPAN};
grpc_millis timeout = 0;
for (grpc_json *field = json->child; field != NULL; field = field->next) {
if (field->key == NULL) continue;
if (strcmp(field->key, "waitForReady") == 0) {
if (wait_for_ready != WAIT_FOR_READY_UNSET) return NULL; // Duplicate.
if (!parse_wait_for_ready(field, &wait_for_ready)) return NULL;
} else if (strcmp(field->key, "timeout") == 0) {
if (timeout.tv_sec > 0 || timeout.tv_nsec > 0) return NULL; // Duplicate.
if (timeout > 0) return NULL; // Duplicate.
if (!parse_timeout(field, &timeout)) return NULL;
}
}
@ -814,7 +816,7 @@ typedef struct client_channel_call_data {
grpc_slice path; // Request path.
gpr_timespec call_start_time;
gpr_timespec deadline;
grpc_millis deadline;
grpc_server_retry_throttle_data *retry_throttle_data;
method_parameters *method_params;
@ -952,11 +954,11 @@ static void apply_service_config_to_call_locked(grpc_exec_ctx *exec_ctx,
// If the deadline from the service config is shorter than the one
// from the client API, reset the deadline timer.
if (chand->deadline_checking_enabled &&
gpr_time_cmp(calld->method_params->timeout,
gpr_time_0(GPR_TIMESPAN)) != 0) {
const gpr_timespec per_method_deadline =
gpr_time_add(calld->call_start_time, calld->method_params->timeout);
if (gpr_time_cmp(per_method_deadline, calld->deadline) < 0) {
calld->method_params->timeout != 0) {
const grpc_millis per_method_deadline =
grpc_timespec_to_millis(calld->call_start_time) +
calld->method_params->timeout;
if (per_method_deadline < calld->deadline) {
calld->deadline = per_method_deadline;
grpc_deadline_state_reset(exec_ctx, elem, calld->deadline);
}
@ -1026,7 +1028,7 @@ static void subchannel_ready_locked(grpc_exec_ctx *exec_ctx,
"Cancelled before creating subchannel", child_errors,
GPR_ARRAY_SIZE(child_errors));
/* if due to deadline, attach the deadline exceeded status to the error */
if (gpr_time_cmp(calld->deadline, gpr_now(GPR_CLOCK_MONOTONIC)) < 0) {
if (calld->deadline < grpc_exec_ctx_now(exec_ctx)) {
cancellation_error =
grpc_error_set_int(cancellation_error, GRPC_ERROR_INT_GRPC_STATUS,
GRPC_STATUS_DEADLINE_EXCEEDED);
@ -1440,7 +1442,7 @@ static grpc_error *cc_init_call_elem(grpc_exec_ctx *exec_ctx,
// Initialize data members.
calld->path = grpc_slice_ref_internal(args->path);
calld->call_start_time = args->start_time;
calld->deadline = gpr_convert_clock_type(args->deadline, GPR_CLOCK_MONOTONIC);
calld->deadline = args->deadline;
calld->owning_call = args->call_stack;
calld->arena = args->arena;
if (chand->deadline_checking_enabled) {

@ -1352,12 +1352,10 @@ static void lb_call_init_locked(grpc_exec_ctx *exec_ctx,
* glb_policy->base.interested_parties, which is comprised of the polling
* entities from \a client_channel. */
grpc_slice host = grpc_slice_from_copied_string(glb_policy->server_name);
gpr_timespec deadline =
grpc_millis deadline =
glb_policy->lb_call_timeout_ms == 0
? gpr_inf_future(GPR_CLOCK_MONOTONIC)
: gpr_time_add(gpr_now(GPR_CLOCK_MONOTONIC),
gpr_time_from_millis(glb_policy->lb_call_timeout_ms,
GPR_TIMESPAN));
? GRPC_MILLIS_INF_FUTURE
: grpc_exec_ctx_now(exec_ctx) + glb_policy->lb_call_timeout_ms;
glb_policy->lb_call = grpc_channel_create_pollset_set_call(
exec_ctx, glb_policy->lb_channel, NULL, GRPC_PROPAGATE_DEFAULTS,
glb_policy->base.interested_parties,

@ -103,7 +103,7 @@ typedef struct {
grpc_polling_entity *pollent;
grpc_slice path;
gpr_timespec start_time;
gpr_timespec deadline;
grpc_millis deadline;
gpr_arena *arena;
grpc_call_context_element *context;
} grpc_connected_subchannel_call_args;

@ -52,9 +52,8 @@ static void timer_callback(grpc_exec_ctx* exec_ctx, void* arg,
// Starts the deadline timer.
static void start_timer_if_needed(grpc_exec_ctx* exec_ctx,
grpc_call_element* elem,
gpr_timespec deadline) {
grpc_millis deadline_millis = grpc_timespec_to_millis(deadline);
if (deadline_millis == GRPC_MILLIS_INF_FUTURE) {
grpc_millis deadline) {
if (deadline == GRPC_MILLIS_INF_FUTURE) {
return;
}
grpc_deadline_state* deadline_state = (grpc_deadline_state*)elem->call_data;
@ -94,7 +93,7 @@ retry:
}
GPR_ASSERT(closure);
GRPC_CALL_STACK_REF(deadline_state->call_stack, "deadline_timer");
grpc_timer_init(exec_ctx, &deadline_state->timer, deadline_millis, closure);
grpc_timer_init(exec_ctx, &deadline_state->timer, deadline, closure);
}
// Cancels the deadline timer.
@ -131,7 +130,7 @@ static void inject_on_complete_cb(grpc_deadline_state* deadline_state,
// initialization has been completed.
struct start_timer_after_init_state {
grpc_call_element* elem;
gpr_timespec deadline;
grpc_millis deadline;
grpc_closure closure;
};
static void start_timer_after_init(grpc_exec_ctx* exec_ctx, void* arg,
@ -143,13 +142,12 @@ static void start_timer_after_init(grpc_exec_ctx* exec_ctx, void* arg,
void grpc_deadline_state_init(grpc_exec_ctx* exec_ctx, grpc_call_element* elem,
grpc_call_stack* call_stack,
gpr_timespec deadline) {
grpc_millis deadline) {
grpc_deadline_state* deadline_state = (grpc_deadline_state*)elem->call_data;
deadline_state->call_stack = call_stack;
// Deadline will always be infinite on servers, so the timer will only be
// set on clients with a finite deadline.
deadline = gpr_convert_clock_type(deadline, GPR_CLOCK_MONOTONIC);
if (gpr_time_cmp(deadline, gpr_inf_future(GPR_CLOCK_MONOTONIC)) != 0) {
if (deadline != GRPC_MILLIS_INF_FUTURE) {
// When the deadline passes, we indicate the failure by sending down
// an op with cancel_error set. However, we can't send down any ops
// until after the call stack is fully initialized. If we start the
@ -173,7 +171,7 @@ void grpc_deadline_state_destroy(grpc_exec_ctx* exec_ctx,
}
void grpc_deadline_state_reset(grpc_exec_ctx* exec_ctx, grpc_call_element* elem,
gpr_timespec new_deadline) {
grpc_millis new_deadline) {
grpc_deadline_state* deadline_state = (grpc_deadline_state*)elem->call_data;
cancel_timer_if_needed(exec_ctx, deadline_state);
start_timer_if_needed(exec_ctx, elem, new_deadline);

@ -50,7 +50,7 @@ typedef struct grpc_deadline_state {
// assumes elem->call_data is zero'd
void grpc_deadline_state_init(grpc_exec_ctx* exec_ctx, grpc_call_element* elem,
grpc_call_stack* call_stack,
gpr_timespec deadline);
grpc_millis deadline);
void grpc_deadline_state_destroy(grpc_exec_ctx* exec_ctx,
grpc_call_element* elem);
@ -62,7 +62,7 @@ void grpc_deadline_state_destroy(grpc_exec_ctx* exec_ctx,
// process of being reset, which means that attempting to increase the
// deadline may result in the timer being called twice.
void grpc_deadline_state_reset(grpc_exec_ctx* exec_ctx, grpc_call_element* elem,
gpr_timespec new_deadline);
grpc_millis new_deadline);
// To be called from the client-side filter's start_transport_stream_op_batch()
// method. Ensures that the deadline timer is cancelled when the call

@ -676,7 +676,7 @@ static int init_stream(grpc_exec_ctx *exec_ctx, grpc_transport *gt,
grpc_chttp2_incoming_metadata_buffer_init(&s->metadata_buffer[1], arena);
grpc_chttp2_data_parser_init(&s->data_parser);
grpc_slice_buffer_init(&s->flow_controlled_buffer);
s->deadline = gpr_inf_future(GPR_CLOCK_MONOTONIC);
s->deadline = GRPC_MILLIS_INF_FUTURE;
GRPC_CLOSURE_INIT(&s->complete_fetch_locked, complete_fetch_locked, s,
grpc_schedule_on_exec_ctx);
grpc_slice_buffer_init(&s->unprocessed_incoming_frames_buffer);
@ -1276,8 +1276,7 @@ static void perform_stream_op_locked(grpc_exec_ctx *exec_ctx, void *stream_op,
t->settings[GRPC_PEER_SETTINGS]
[GRPC_CHTTP2_SETTINGS_MAX_HEADER_LIST_SIZE];
if (t->is_client) {
s->deadline =
gpr_time_min(s->deadline, s->send_initial_metadata->deadline);
s->deadline = GPR_MIN(s->deadline, s->send_initial_metadata->deadline);
}
if (metadata_size > metadata_peer_limit) {
grpc_chttp2_cancel_stream(
@ -1473,16 +1472,14 @@ static void perform_stream_op(grpc_exec_ctx *exec_ctx, grpc_transport *gt,
if (!t->is_client) {
if (op->send_initial_metadata) {
gpr_timespec deadline =
grpc_millis deadline =
op->payload->send_initial_metadata.send_initial_metadata->deadline;
GPR_ASSERT(0 ==
gpr_time_cmp(gpr_inf_future(deadline.clock_type), deadline));
GPR_ASSERT(deadline == GRPC_MILLIS_INF_FUTURE);
}
if (op->send_trailing_metadata) {
gpr_timespec deadline =
grpc_millis deadline =
op->payload->send_trailing_metadata.send_trailing_metadata->deadline;
GPR_ASSERT(0 ==
gpr_time_cmp(gpr_inf_future(deadline.clock_type), deadline));
GPR_ASSERT(deadline == GRPC_MILLIS_INF_FUTURE);
}
}
@ -1556,8 +1553,8 @@ static void send_goaway(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t,
t->sent_goaway_state = GRPC_CHTTP2_GOAWAY_SEND_SCHEDULED;
grpc_http2_error_code http_error;
grpc_slice slice;
grpc_error_get_status(error, gpr_inf_future(GPR_CLOCK_MONOTONIC), NULL,
&slice, &http_error);
grpc_error_get_status(exec_ctx, error, GRPC_MILLIS_INF_FUTURE, NULL, &slice,
&http_error);
grpc_chttp2_goaway_append(t->last_new_stream_id, (uint32_t)http_error,
grpc_slice_ref_internal(slice), &t->qbuf);
grpc_chttp2_initiate_write(exec_ctx, t, "goaway_sent");
@ -1786,7 +1783,8 @@ void grpc_chttp2_cancel_stream(grpc_exec_ctx *exec_ctx,
if (!s->read_closed || !s->write_closed) {
if (s->id != 0) {
grpc_http2_error_code http_error;
grpc_error_get_status(due_to_error, s->deadline, NULL, NULL, &http_error);
grpc_error_get_status(exec_ctx, due_to_error, s->deadline, NULL, NULL,
&http_error);
grpc_slice_buffer_add(
&t->qbuf, grpc_chttp2_rst_stream_create(s->id, (uint32_t)http_error,
&s->stats.outgoing));
@ -1803,7 +1801,7 @@ void grpc_chttp2_fake_status(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t,
grpc_chttp2_stream *s, grpc_error *error) {
grpc_status_code status;
grpc_slice slice;
grpc_error_get_status(error, s->deadline, &status, &slice, NULL);
grpc_error_get_status(exec_ctx, error, s->deadline, &status, &slice, NULL);
if (status != GRPC_STATUS_OK) {
s->seen_error = true;
@ -1960,7 +1958,8 @@ static void close_from_api(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t,
uint32_t len = 0;
grpc_status_code grpc_status;
grpc_slice slice;
grpc_error_get_status(error, s->deadline, &grpc_status, &slice, NULL);
grpc_error_get_status(exec_ctx, error, s->deadline, &grpc_status, &slice,
NULL);
GPR_ASSERT(grpc_status >= 0 && (int)grpc_status < 100);

@ -515,12 +515,12 @@ static void hpack_enc(grpc_exec_ctx *exec_ctx, grpc_chttp2_hpack_compressor *c,
#define TIMEOUT_KEY "grpc-timeout"
static void deadline_enc(grpc_exec_ctx *exec_ctx,
grpc_chttp2_hpack_compressor *c, gpr_timespec deadline,
grpc_chttp2_hpack_compressor *c, grpc_millis deadline,
framer_state *st) {
char timeout_str[GRPC_HTTP2_TIMEOUT_ENCODE_MIN_BUFSIZE];
grpc_mdelem mdelem;
grpc_http2_encode_timeout(
gpr_time_sub(deadline, gpr_now(deadline.clock_type)), timeout_str);
grpc_http2_encode_timeout(deadline - grpc_exec_ctx_now(exec_ctx),
timeout_str);
mdelem = grpc_mdelem_from_slices(exec_ctx, GRPC_MDSTR_GRPC_TIMEOUT,
grpc_slice_from_copied_string(timeout_str));
hpack_enc(exec_ctx, c, mdelem, st);
@ -639,8 +639,8 @@ void grpc_chttp2_encode_header(grpc_exec_ctx *exec_ctx,
for (grpc_linked_mdelem *l = metadata->list.head; l; l = l->next) {
hpack_enc(exec_ctx, c, l->md, &st);
}
gpr_timespec deadline = metadata->deadline;
if (gpr_time_cmp(deadline, gpr_inf_future(deadline.clock_type)) != 0) {
grpc_millis deadline = metadata->deadline;
if (deadline != GRPC_MILLIS_INF_FUTURE) {
deadline_enc(exec_ctx, c, deadline, &st);
}

@ -29,7 +29,7 @@ void grpc_chttp2_incoming_metadata_buffer_init(
grpc_chttp2_incoming_metadata_buffer *buffer, gpr_arena *arena) {
buffer->arena = arena;
grpc_metadata_batch_init(&buffer->batch);
buffer->batch.deadline = gpr_inf_future(GPR_CLOCK_REALTIME);
buffer->batch.deadline = GRPC_MILLIS_INF_FUTURE;
}
void grpc_chttp2_incoming_metadata_buffer_destroy(
@ -61,7 +61,7 @@ grpc_error *grpc_chttp2_incoming_metadata_buffer_replace_or_add(
}
void grpc_chttp2_incoming_metadata_buffer_set_deadline(
grpc_chttp2_incoming_metadata_buffer *buffer, gpr_timespec deadline) {
grpc_chttp2_incoming_metadata_buffer *buffer, grpc_millis deadline) {
buffer->batch.deadline = deadline;
}

@ -43,6 +43,6 @@ grpc_error *grpc_chttp2_incoming_metadata_buffer_replace_or_add(
grpc_exec_ctx *exec_ctx, grpc_chttp2_incoming_metadata_buffer *buffer,
grpc_mdelem elem) GRPC_MUST_USE_RESULT;
void grpc_chttp2_incoming_metadata_buffer_set_deadline(
grpc_chttp2_incoming_metadata_buffer *buffer, gpr_timespec deadline);
grpc_chttp2_incoming_metadata_buffer *buffer, grpc_millis deadline);
#endif /* GRPC_CORE_EXT_TRANSPORT_CHTTP2_TRANSPORT_INCOMING_METADATA_H */

@ -499,7 +499,7 @@ struct grpc_chttp2_stream {
grpc_error *byte_stream_error; /* protected by t combiner */
bool received_last_frame; /* protected by t combiner */
gpr_timespec deadline;
grpc_millis deadline;
/** saw some stream level error */
grpc_error *forced_close_error;

@ -494,16 +494,16 @@ static void on_initial_header(grpc_exec_ctx *exec_ctx, void *tp,
}
if (grpc_slice_eq(GRPC_MDKEY(md), GRPC_MDSTR_GRPC_TIMEOUT)) {
gpr_timespec *cached_timeout = grpc_mdelem_get_user_data(md, free_timeout);
gpr_timespec timeout;
grpc_millis *cached_timeout = grpc_mdelem_get_user_data(md, free_timeout);
grpc_millis timeout;
if (cached_timeout == NULL) {
/* not already parsed: parse it now, and store the result away */
cached_timeout = gpr_malloc(sizeof(gpr_timespec));
cached_timeout = gpr_malloc(sizeof(grpc_millis));
if (!grpc_http2_decode_timeout(GRPC_MDVALUE(md), cached_timeout)) {
char *val = grpc_slice_to_c_string(GRPC_MDVALUE(md));
gpr_log(GPR_ERROR, "Ignoring bad timeout value '%s'", val);
gpr_free(val);
*cached_timeout = gpr_inf_future(GPR_TIMESPAN);
*cached_timeout = GRPC_MILLIS_INF_FUTURE;
}
timeout = *cached_timeout;
grpc_mdelem_set_user_data(md, free_timeout, cached_timeout);
@ -511,8 +511,7 @@ static void on_initial_header(grpc_exec_ctx *exec_ctx, void *tp,
timeout = *cached_timeout;
}
grpc_chttp2_incoming_metadata_buffer_set_deadline(
&s->metadata_buffer[0],
gpr_time_add(gpr_now(GPR_CLOCK_MONOTONIC), timeout));
&s->metadata_buffer[0], grpc_exec_ctx_now(exec_ctx) + timeout);
GRPC_MDELEM_UNREF(exec_ctx, md);
} else {
const size_t new_size = s->metadata_buffer[0].size + GRPC_MDELEM_LENGTH(md);

@ -150,7 +150,7 @@ typedef struct inproc_stream {
grpc_metadata_batch write_buffer_initial_md;
bool write_buffer_initial_md_filled;
uint32_t write_buffer_initial_md_flags;
gpr_timespec write_buffer_deadline;
grpc_millis write_buffer_deadline;
slice_buffer_list write_buffer_message;
grpc_metadata_batch write_buffer_trailing_md;
bool write_buffer_trailing_md_filled;
@ -180,7 +180,7 @@ typedef struct inproc_stream {
grpc_error *cancel_self_error;
grpc_error *cancel_other_error;
gpr_timespec deadline;
grpc_millis deadline;
bool listed;
struct inproc_stream *stream_list_prev;
@ -358,8 +358,8 @@ static int init_stream(grpc_exec_ctx *exec_ctx, grpc_transport *gt,
s->cancel_self_error = GRPC_ERROR_NONE;
s->cancel_other_error = GRPC_ERROR_NONE;
s->write_buffer_cancel_error = GRPC_ERROR_NONE;
s->deadline = gpr_inf_future(GPR_CLOCK_MONOTONIC);
s->write_buffer_deadline = gpr_inf_future(GPR_CLOCK_MONOTONIC);
s->deadline = GRPC_MILLIS_INF_FUTURE;
s->write_buffer_deadline = GRPC_MILLIS_INF_FUTURE;
s->stream_list_prev = NULL;
gpr_mu_lock(&t->mu->mu);
@ -402,7 +402,7 @@ static int init_stream(grpc_exec_ctx *exec_ctx, grpc_transport *gt,
cs->write_buffer_initial_md_flags,
&s->to_read_initial_md, &s->to_read_initial_md_flags,
&s->to_read_initial_md_filled);
s->deadline = gpr_time_min(s->deadline, cs->write_buffer_deadline);
s->deadline = GPR_MIN(s->deadline, cs->write_buffer_deadline);
grpc_metadata_batch_clear(exec_ctx, &cs->write_buffer_initial_md);
cs->write_buffer_initial_md_filled = false;
}
@ -935,10 +935,10 @@ static void perform_stream_op(grpc_exec_ctx *exec_ctx, grpc_transport *gt,
dest, destflags, destfilled);
}
if (s->t->is_client) {
gpr_timespec *dl =
grpc_millis *dl =
(other == NULL) ? &s->write_buffer_deadline : &other->deadline;
*dl = gpr_time_min(*dl, op->payload->send_initial_metadata
.send_initial_metadata->deadline);
*dl = GPR_MIN(*dl, op->payload->send_initial_metadata
.send_initial_metadata->deadline);
s->initial_md_sent = true;
}
}

@ -69,7 +69,7 @@ typedef struct {
grpc_call_context_element *context;
grpc_slice path;
gpr_timespec start_time;
gpr_timespec deadline;
grpc_millis deadline;
gpr_arena *arena;
} grpc_call_element_args;

@ -202,7 +202,7 @@ struct grpc_call {
server, it's trailing metadata */
grpc_linked_mdelem send_extra_metadata[MAX_SEND_EXTRA_METADATA_COUNT];
int send_extra_metadata_count;
gpr_timespec send_deadline;
grpc_millis send_deadline;
grpc_slice_buffer_stream sending_stream;
@ -252,7 +252,7 @@ static void destroy_call(grpc_exec_ctx *exec_ctx, void *call_stack,
grpc_error *error);
static void receiving_slice_ready(grpc_exec_ctx *exec_ctx, void *bctlp,
grpc_error *error);
static void get_final_status(grpc_call *call,
static void get_final_status(grpc_exec_ctx *exec_ctx, grpc_call *call,
void (*set_value)(grpc_status_code code,
void *user_data),
void *set_value_user_data, grpc_slice *details);
@ -334,11 +334,10 @@ grpc_error *grpc_call_create(grpc_exec_ctx *exec_ctx,
}
for (i = 0; i < 2; i++) {
for (j = 0; j < 2; j++) {
call->metadata_batch[i][j].deadline = gpr_inf_future(GPR_CLOCK_MONOTONIC);
call->metadata_batch[i][j].deadline = GRPC_MILLIS_INF_FUTURE;
}
}
gpr_timespec send_deadline =
gpr_convert_clock_type(args->send_deadline, GPR_CLOCK_MONOTONIC);
grpc_millis send_deadline = args->send_deadline;
bool immediately_cancel = false;
@ -356,10 +355,7 @@ grpc_error *grpc_call_create(grpc_exec_ctx *exec_ctx,
gpr_mu_lock(&pc->child_list_mu);
if (args->propagation_mask & GRPC_PROPAGATE_DEADLINE) {
send_deadline = gpr_time_min(
gpr_convert_clock_type(send_deadline,
args->parent_call->send_deadline.clock_type),
args->parent_call->send_deadline);
send_deadline = GPR_MIN(send_deadline, args->parent_call->send_deadline);
}
/* for now GRPC_PROPAGATE_TRACING_CONTEXT *MUST* be passed with
* GRPC_PROPAGATE_STATS_CONTEXT */
@ -511,8 +507,8 @@ static void destroy_call(grpc_exec_ctx *exec_ctx, void *call,
GRPC_CQ_INTERNAL_UNREF(exec_ctx, c->cq, "bind");
}
get_final_status(call, set_status_value_directly, &c->final_info.final_status,
NULL);
get_final_status(exec_ctx, call, set_status_value_directly,
&c->final_info.final_status, NULL);
c->final_info.stats.latency =
gpr_time_sub(gpr_now(GPR_CLOCK_MONOTONIC), c->start_time);
@ -662,13 +658,16 @@ static void cancel_with_status(grpc_exec_ctx *exec_ctx, grpc_call *c,
* FINAL STATUS CODE MANIPULATION
*/
static bool get_final_status_from(
grpc_call *call, grpc_error *error, bool allow_ok_status,
void (*set_value)(grpc_status_code code, void *user_data),
void *set_value_user_data, grpc_slice *details) {
static bool get_final_status_from(grpc_exec_ctx *exec_ctx, grpc_call *call,
grpc_error *error, bool allow_ok_status,
void (*set_value)(grpc_status_code code,
void *user_data),
void *set_value_user_data,
grpc_slice *details) {
grpc_status_code code;
grpc_slice slice = grpc_empty_slice();
grpc_error_get_status(error, call->send_deadline, &code, &slice, NULL);
grpc_error_get_status(exec_ctx, error, call->send_deadline, &code, &slice,
NULL);
if (code == GRPC_STATUS_OK && !allow_ok_status) {
return false;
}
@ -680,7 +679,7 @@ static bool get_final_status_from(
return true;
}
static void get_final_status(grpc_call *call,
static void get_final_status(grpc_exec_ctx *exec_ctx, grpc_call *call,
void (*set_value)(grpc_status_code code,
void *user_data),
void *set_value_user_data, grpc_slice *details) {
@ -705,8 +704,9 @@ static void get_final_status(grpc_call *call,
for (i = 0; i < STATUS_SOURCE_COUNT; i++) {
if (status[i].is_set &&
grpc_error_has_clear_grpc_status(status[i].error)) {
if (get_final_status_from(call, status[i].error, allow_ok_status != 0,
set_value, set_value_user_data, details)) {
if (get_final_status_from(exec_ctx, call, status[i].error,
allow_ok_status != 0, set_value,
set_value_user_data, details)) {
return;
}
}
@ -714,8 +714,9 @@ static void get_final_status(grpc_call *call,
/* If no clearly defined status exists, search for 'anything' */
for (i = 0; i < STATUS_SOURCE_COUNT; i++) {
if (status[i].is_set) {
if (get_final_status_from(call, status[i].error, allow_ok_status != 0,
set_value, set_value_user_data, details)) {
if (get_final_status_from(exec_ctx, call, status[i].error,
allow_ok_status != 0, set_value,
set_value_user_data, details)) {
return;
}
}
@ -1146,11 +1147,11 @@ static void post_batch_completion(grpc_exec_ctx *exec_ctx,
}
if (call->is_client) {
get_final_status(call, set_status_value_directly,
get_final_status(exec_ctx, call, set_status_value_directly,
call->final_op.client.status,
call->final_op.client.status_details);
} else {
get_final_status(call, set_cancelled_value,
get_final_status(exec_ctx, call, set_cancelled_value,
call->final_op.server.cancelled, NULL);
}
@ -1371,11 +1372,8 @@ static void receiving_initial_metadata_ready(grpc_exec_ctx *exec_ctx,
validate_filtered_metadata(exec_ctx, bctl);
GPR_TIMER_END("validate_filtered_metadata", 0);
if (gpr_time_cmp(md->deadline, gpr_inf_future(md->deadline.clock_type)) !=
0 &&
!call->is_client) {
call->send_deadline =
gpr_convert_clock_type(md->deadline, GPR_CLOCK_MONOTONIC);
if (md->deadline != GRPC_MILLIS_INF_FUTURE && !call->is_client) {
call->send_deadline = md->deadline;
}
}

@ -49,7 +49,7 @@ typedef struct grpc_call_create_args {
grpc_mdelem *add_initial_metadata;
size_t add_initial_metadata_count;
gpr_timespec send_deadline;
grpc_millis send_deadline;
} grpc_call_create_args;
/* Create a new call based on \a args.

@ -230,7 +230,7 @@ static grpc_call *grpc_channel_create_call_internal(
grpc_exec_ctx *exec_ctx, grpc_channel *channel, grpc_call *parent_call,
uint32_t propagation_mask, grpc_completion_queue *cq,
grpc_pollset_set *pollset_set_alternative, grpc_mdelem path_mdelem,
grpc_mdelem authority_mdelem, gpr_timespec deadline) {
grpc_mdelem authority_mdelem, grpc_millis deadline) {
grpc_mdelem send_metadata[2];
size_t num_metadata = 0;
@ -276,7 +276,7 @@ grpc_call *grpc_channel_create_call(grpc_channel *channel,
host != NULL ? grpc_mdelem_from_slices(&exec_ctx, GRPC_MDSTR_AUTHORITY,
grpc_slice_ref_internal(*host))
: GRPC_MDNULL,
deadline);
grpc_timespec_to_millis(deadline));
grpc_exec_ctx_finish(&exec_ctx);
return call;
}
@ -284,7 +284,7 @@ grpc_call *grpc_channel_create_call(grpc_channel *channel,
grpc_call *grpc_channel_create_pollset_set_call(
grpc_exec_ctx *exec_ctx, grpc_channel *channel, grpc_call *parent_call,
uint32_t propagation_mask, grpc_pollset_set *pollset_set, grpc_slice method,
const grpc_slice *host, gpr_timespec deadline, void *reserved) {
const grpc_slice *host, grpc_millis deadline, void *reserved) {
GPR_ASSERT(!reserved);
return grpc_channel_create_call_internal(
exec_ctx, channel, parent_call, propagation_mask, NULL, pollset_set,
@ -340,7 +340,8 @@ grpc_call *grpc_channel_create_registered_call(
grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
grpc_call *call = grpc_channel_create_call_internal(
&exec_ctx, channel, parent_call, propagation_mask, completion_queue, NULL,
GRPC_MDELEM_REF(rc->path), GRPC_MDELEM_REF(rc->authority), deadline);
GRPC_MDELEM_REF(rc->path), GRPC_MDELEM_REF(rc->authority),
grpc_timespec_to_millis(deadline));
grpc_exec_ctx_finish(&exec_ctx);
return call;
}

@ -43,7 +43,7 @@ grpc_channel *grpc_channel_create_with_builder(
grpc_call *grpc_channel_create_pollset_set_call(
grpc_exec_ctx *exec_ctx, grpc_channel *channel, grpc_call *parent_call,
uint32_t propagation_mask, grpc_pollset_set *pollset_set, grpc_slice method,
const grpc_slice *host, gpr_timespec deadline, void *reserved);
const grpc_slice *host, grpc_millis deadline, void *reserved);
/** Get a (borrowed) pointer to this channels underlying channel stack */
grpc_channel_stack *grpc_channel_get_channel_stack(grpc_channel *channel);

@ -73,7 +73,7 @@ static void fill_metadata(grpc_exec_ctx *exec_ctx, grpc_call_element *elem,
mdb->list.head = &calld->status;
mdb->list.tail = &calld->details;
mdb->list.count = 2;
mdb->deadline = gpr_inf_future(GPR_CLOCK_REALTIME);
mdb->deadline = GRPC_MILLIS_INF_FUTURE;
}
static void lame_start_transport_stream_op_batch(

@ -136,7 +136,7 @@ struct call_data {
bool host_set;
grpc_slice path;
grpc_slice host;
gpr_timespec deadline;
grpc_millis deadline;
grpc_completion_queue *cq_new;
@ -489,11 +489,13 @@ static void publish_call(grpc_exec_ctx *exec_ctx, grpc_server *server,
GPR_ASSERT(calld->path_set);
rc->data.batch.details->host = grpc_slice_ref_internal(calld->host);
rc->data.batch.details->method = grpc_slice_ref_internal(calld->path);
rc->data.batch.details->deadline = calld->deadline;
rc->data.batch.details->deadline =
grpc_millis_to_timespec(calld->deadline, GPR_CLOCK_REALTIME);
rc->data.batch.details->flags = calld->recv_initial_metadata_flags;
break;
case REGISTERED_CALL:
*rc->data.registered.deadline = calld->deadline;
*rc->data.registered.deadline =
grpc_millis_to_timespec(calld->deadline, GPR_CLOCK_REALTIME);
if (rc->data.registered.optional_payload) {
*rc->data.registered.optional_payload = calld->payload;
calld->payload = NULL;
@ -734,7 +736,7 @@ static void server_on_recv_initial_metadata(grpc_exec_ctx *exec_ctx, void *ptr,
grpc_error *error) {
grpc_call_element *elem = ptr;
call_data *calld = elem->call_data;
gpr_timespec op_deadline;
grpc_millis op_deadline;
if (error == GRPC_ERROR_NONE) {
GPR_ASSERT(calld->recv_initial_metadata->idx.named.path != NULL);
@ -754,7 +756,7 @@ static void server_on_recv_initial_metadata(grpc_exec_ctx *exec_ctx, void *ptr,
GRPC_ERROR_REF(error);
}
op_deadline = calld->recv_initial_metadata->deadline;
if (0 != gpr_time_cmp(op_deadline, gpr_inf_future(op_deadline.clock_type))) {
if (op_deadline != GRPC_MILLIS_INF_FUTURE) {
calld->deadline = op_deadline;
}
if (calld->host_set && calld->path_set) {
@ -829,7 +831,7 @@ static void accept_stream(grpc_exec_ctx *exec_ctx, void *cd,
memset(&args, 0, sizeof(args));
args.channel = chand->channel;
args.server_transport_data = transport_server_data;
args.send_deadline = gpr_inf_future(GPR_CLOCK_MONOTONIC);
args.send_deadline = GRPC_MILLIS_INF_FUTURE;
grpc_call *call;
grpc_error *error = grpc_call_create(exec_ctx, &args, &call);
grpc_call_element *elem =
@ -877,7 +879,7 @@ static grpc_error *init_call_elem(grpc_exec_ctx *exec_ctx,
call_data *calld = elem->call_data;
channel_data *chand = elem->channel_data;
memset(calld, 0, sizeof(call_data));
calld->deadline = gpr_inf_future(GPR_CLOCK_REALTIME);
calld->deadline = GRPC_MILLIS_INF_FUTURE;
calld->call = grpc_call_from_top_element(elem);
gpr_mu_init(&calld->mu_state);

@ -39,8 +39,9 @@ static grpc_error *recursively_find_error_with_field(grpc_error *error,
return NULL;
}
void grpc_error_get_status(grpc_error *error, gpr_timespec deadline,
grpc_status_code *code, grpc_slice *slice,
void grpc_error_get_status(grpc_exec_ctx *exec_ctx, grpc_error *error,
grpc_millis deadline, grpc_status_code *code,
grpc_slice *slice,
grpc_http2_error_code *http_error) {
// Start with the parent error and recurse through the tree of children
// until we find the first one that has a status code.
@ -63,8 +64,8 @@ void grpc_error_get_status(grpc_error *error, gpr_timespec deadline,
status = (grpc_status_code)integer;
} else if (grpc_error_get_int(found_error, GRPC_ERROR_INT_HTTP2_ERROR,
&integer)) {
status = grpc_http2_error_to_grpc_status((grpc_http2_error_code)integer,
deadline);
status = grpc_http2_error_to_grpc_status(
exec_ctx, (grpc_http2_error_code)integer, deadline);
}
if (code != NULL) *code = status;

@ -20,6 +20,7 @@
#define GRPC_CORE_LIB_TRANSPORT_ERROR_UTILS_H
#include "src/core/lib/iomgr/error.h"
#include "src/core/lib/iomgr/exec_ctx.h"
#include "src/core/lib/transport/http2_errors.h"
/// A utility function to get the status code and message to be returned
@ -28,8 +29,9 @@
/// All attributes are pulled from the same child error. If any of the
/// attributes (code, msg, http_status) are unneeded, they can be passed as
/// NULL.
void grpc_error_get_status(grpc_error *error, gpr_timespec deadline,
grpc_status_code *code, grpc_slice *slice,
void grpc_error_get_status(grpc_exec_ctx *exec_ctx, grpc_error *error,
grpc_millis deadline, grpc_status_code *code,
grpc_slice *slice,
grpc_http2_error_code *http_status);
/// A utility function to check whether there is a clear status code that

@ -74,7 +74,7 @@ void grpc_metadata_batch_assert_ok(grpc_metadata_batch *batch) {
void grpc_metadata_batch_init(grpc_metadata_batch *batch) {
memset(batch, 0, sizeof(*batch));
batch->deadline = gpr_inf_future(GPR_CLOCK_REALTIME);
batch->deadline = GRPC_MILLIS_INF_FUTURE;
}
void grpc_metadata_batch_destroy(grpc_exec_ctx *exec_ctx,
@ -268,9 +268,7 @@ void grpc_metadata_batch_clear(grpc_exec_ctx *exec_ctx,
}
bool grpc_metadata_batch_is_empty(grpc_metadata_batch *batch) {
return batch->list.head == NULL &&
gpr_time_cmp(gpr_inf_future(batch->deadline.clock_type),
batch->deadline) == 0;
return batch->list.head == NULL && batch->deadline == GRPC_MILLIS_INF_FUTURE;
}
size_t grpc_metadata_batch_size(grpc_metadata_batch *batch) {

@ -50,9 +50,9 @@ typedef struct grpc_metadata_batch {
grpc_mdelem_list list;
grpc_metadata_batch_callouts idx;
/** Used to calculate grpc-timeout at the point of sending,
or gpr_inf_future if this batch does not need to send a
or GRPC_MILLIS_INF_FUTURE if this batch does not need to send a
grpc-timeout */
gpr_timespec deadline;
grpc_millis deadline;
} grpc_metadata_batch;
void grpc_metadata_batch_init(grpc_metadata_batch *batch);

@ -37,8 +37,9 @@ int grpc_status_to_http2_error(grpc_status_code status) {
}
}
grpc_status_code grpc_http2_error_to_grpc_status(grpc_http2_error_code error,
gpr_timespec deadline) {
grpc_status_code grpc_http2_error_to_grpc_status(grpc_exec_ctx *exec_ctx,
grpc_http2_error_code error,
grpc_millis deadline) {
switch (error) {
case GRPC_HTTP2_NO_ERROR:
/* should never be received */
@ -46,7 +47,7 @@ grpc_status_code grpc_http2_error_to_grpc_status(grpc_http2_error_code error,
case GRPC_HTTP2_CANCEL:
/* http2 cancel translates to STATUS_CANCELLED iff deadline hasn't been
* exceeded */
return gpr_time_cmp(gpr_now(deadline.clock_type), deadline) >= 0
return grpc_exec_ctx_now(exec_ctx) > deadline
? GRPC_STATUS_DEADLINE_EXCEEDED
: GRPC_STATUS_CANCELLED;
case GRPC_HTTP2_ENHANCE_YOUR_CALM:

@ -20,12 +20,14 @@
#define GRPC_CORE_LIB_TRANSPORT_STATUS_CONVERSION_H
#include <grpc/grpc.h>
#include "src/core/lib/iomgr/exec_ctx.h"
#include "src/core/lib/transport/http2_errors.h"
/* Conversion of grpc status codes to http2 error codes (for RST_STREAM) */
grpc_http2_error_code grpc_status_to_http2_error(grpc_status_code status);
grpc_status_code grpc_http2_error_to_grpc_status(grpc_http2_error_code error,
gpr_timespec deadline);
grpc_status_code grpc_http2_error_to_grpc_status(grpc_exec_ctx *exec_ctx,
grpc_http2_error_code error,
grpc_millis deadline);
/* Conversion of HTTP status codes (:status) to grpc status codes */
grpc_status_code grpc_http2_status_to_grpc_status(int status);

@ -59,60 +59,27 @@ static void enc_seconds(char *buffer, int64_t sec) {
}
}
static void enc_nanos(char *buffer, int64_t x) {
static void enc_millis(char *buffer, int64_t x) {
x = round_up_to_three_sig_figs(x);
if (x < 100000) {
if (x % 1000 == 0) {
enc_ext(buffer, x / 1000, 'u');
} else {
enc_ext(buffer, x, 'n');
}
} else if (x < 100000000) {
if (x % 1000000 == 0) {
enc_ext(buffer, x / 1000000, 'm');
} else {
enc_ext(buffer, x / 1000, 'u');
}
} else if (x < 1000000000) {
enc_ext(buffer, x / 1000000, 'm');
if (x < GPR_MS_PER_SEC) {
enc_ext(buffer, x, 'm');
} else {
/* note that this is only ever called with times of less than one second,
so if we reach here the time must have been rounded up to a whole second
(and no more) */
memcpy(buffer, "1S", 3);
}
}
static void enc_micros(char *buffer, int64_t x) {
x = round_up_to_three_sig_figs(x);
if (x < 100000) {
if (x % 1000 == 0) {
enc_ext(buffer, x / 1000, 'm');
if (x % GPR_MS_PER_SEC == 0) {
enc_seconds(buffer, x / GPR_MS_PER_SEC);
} else {
enc_ext(buffer, x, 'u');
enc_ext(buffer, x, 'm');
}
} else if (x < 100000000) {
if (x % 1000000 == 0) {
enc_ext(buffer, x / 1000000, 'S');
} else {
enc_ext(buffer, x / 1000, 'm');
}
} else {
enc_ext(buffer, x / 1000000, 'S');
}
}
void grpc_http2_encode_timeout(gpr_timespec timeout, char *buffer) {
if (timeout.tv_sec < 0) {
void grpc_http2_encode_timeout(grpc_millis timeout, char *buffer) {
if (timeout <= 0) {
enc_tiny(buffer);
} else if (timeout.tv_sec == 0) {
enc_nanos(buffer, timeout.tv_nsec);
} else if (timeout.tv_sec < 1000 && timeout.tv_nsec != 0) {
enc_micros(buffer,
(int64_t)(timeout.tv_sec * 1000000) +
(timeout.tv_nsec / 1000 + (timeout.tv_nsec % 1000 != 0)));
} else if (timeout < 1000 * GPR_MS_PER_SEC) {
enc_millis(buffer, timeout);
} else {
enc_seconds(buffer, timeout.tv_sec + (timeout.tv_nsec != 0));
enc_seconds(buffer,
timeout / GPR_MS_PER_SEC + (timeout % GPR_MS_PER_SEC != 0));
}
}
@ -121,7 +88,7 @@ static int is_all_whitespace(const char *p, const char *end) {
return p == end;
}
int grpc_http2_decode_timeout(grpc_slice text, gpr_timespec *timeout) {
int grpc_http2_decode_timeout(grpc_slice text, grpc_millis *timeout) {
int32_t x = 0;
const uint8_t *p = GRPC_SLICE_START_PTR(text);
const uint8_t *end = GRPC_SLICE_END_PTR(text);
@ -136,7 +103,7 @@ int grpc_http2_decode_timeout(grpc_slice text, gpr_timespec *timeout) {
/* spec allows max. 8 digits, but we allow values up to 1,000,000,000 */
if (x >= (100 * 1000 * 1000)) {
if (x != (100 * 1000 * 1000) || digit != 0) {
*timeout = gpr_inf_future(GPR_TIMESPAN);
*timeout = GRPC_MILLIS_INF_FUTURE;
return 1;
}
}
@ -150,22 +117,22 @@ int grpc_http2_decode_timeout(grpc_slice text, gpr_timespec *timeout) {
/* decode unit specifier */
switch (*p) {
case 'n':
*timeout = gpr_time_from_nanos(x, GPR_TIMESPAN);
*timeout = x / GPR_NS_PER_MS + (x % GPR_NS_PER_MS != 0);
break;
case 'u':
*timeout = gpr_time_from_micros(x, GPR_TIMESPAN);
*timeout = x / GPR_US_PER_MS + (x % GPR_US_PER_MS != 0);
break;
case 'm':
*timeout = gpr_time_from_millis(x, GPR_TIMESPAN);
*timeout = x;
break;
case 'S':
*timeout = gpr_time_from_seconds(x, GPR_TIMESPAN);
*timeout = x * GPR_MS_PER_SEC;
break;
case 'M':
*timeout = gpr_time_from_minutes(x, GPR_TIMESPAN);
*timeout = x * 60 * GPR_MS_PER_SEC;
break;
case 'H':
*timeout = gpr_time_from_hours(x, GPR_TIMESPAN);
*timeout = x * 60 * 60 * GPR_MS_PER_SEC;
break;
default:
return 0;

@ -22,13 +22,14 @@
#include <grpc/slice.h>
#include <grpc/support/time.h>
#include "src/core/lib/iomgr/exec_ctx.h"
#include "src/core/lib/support/string.h"
#define GRPC_HTTP2_TIMEOUT_ENCODE_MIN_BUFSIZE (GPR_LTOA_MIN_BUFSIZE + 1)
/* Encode/decode timeouts to the GRPC over HTTP/2 format;
encoding may round up arbitrarily */
void grpc_http2_encode_timeout(gpr_timespec timeout, char *buffer);
int grpc_http2_decode_timeout(grpc_slice text, gpr_timespec *timeout);
void grpc_http2_encode_timeout(grpc_millis timeout, char *buffer);
int grpc_http2_decode_timeout(grpc_slice text, grpc_millis *timeout);
#endif /* GRPC_CORE_LIB_TRANSPORT_TIMEOUT_ENCODING_H */

@ -48,10 +48,9 @@ static void put_metadata_list(gpr_strvec *b, grpc_metadata_batch md) {
if (m != md.list.head) gpr_strvec_add(b, gpr_strdup(", "));
put_metadata(b, m->md);
}
if (gpr_time_cmp(md.deadline, gpr_inf_future(md.deadline.clock_type)) != 0) {
if (md.deadline != GRPC_MILLIS_INF_FUTURE) {
char *tmp;
gpr_asprintf(&tmp, " deadline=%" PRId64 ".%09d", md.deadline.tv_sec,
md.deadline.tv_nsec);
gpr_asprintf(&tmp, " deadline=%" PRIdPTR, md.deadline);
gpr_strvec_add(b, tmp);
}
}

@ -130,7 +130,7 @@ static void test_create_channel_stack(void) {
.context = NULL,
.path = path,
.start_time = gpr_now(GPR_CLOCK_MONOTONIC),
.deadline = gpr_inf_future(GPR_CLOCK_MONOTONIC),
.deadline = GRPC_MILLIS_INF_FUTURE,
.arena = NULL};
grpc_error *error = grpc_call_stack_init(&exec_ctx, channel_stack, 1,
free_call, call_stack, &args);

@ -22,8 +22,13 @@
#define GRPC_STATUS_TO_HTTP2_ERROR(a, b) \
GPR_ASSERT(grpc_status_to_http2_error(a) == (b))
#define HTTP2_ERROR_TO_GRPC_STATUS(a, deadline, b) \
GPR_ASSERT(grpc_http2_error_to_grpc_status(a, deadline) == (b))
#define HTTP2_ERROR_TO_GRPC_STATUS(a, deadline, b) \
do { \
grpc_exec_ctx my_exec_ctx = GRPC_EXEC_CTX_INIT; \
GPR_ASSERT(grpc_http2_error_to_grpc_status(&my_exec_ctx, a, deadline) == \
(b)); \
grpc_exec_ctx_finish(&my_exec_ctx); \
} while (0)
#define GRPC_STATUS_TO_HTTP2_STATUS(a, b) \
GPR_ASSERT(grpc_status_to_http2_status(a) == (b))
#define HTTP2_STATUS_TO_GRPC_STATUS(a, b) \
@ -79,7 +84,7 @@ int main(int argc, char **argv) {
GRPC_STATUS_TO_HTTP2_STATUS(GRPC_STATUS_UNAVAILABLE, 200);
GRPC_STATUS_TO_HTTP2_STATUS(GRPC_STATUS_DATA_LOSS, 200);
const gpr_timespec before_deadline = gpr_inf_future(GPR_CLOCK_MONOTONIC);
const grpc_millis before_deadline = GRPC_MILLIS_INF_FUTURE;
HTTP2_ERROR_TO_GRPC_STATUS(GRPC_HTTP2_NO_ERROR, before_deadline,
GRPC_STATUS_INTERNAL);
HTTP2_ERROR_TO_GRPC_STATUS(GRPC_HTTP2_PROTOCOL_ERROR, before_deadline,
@ -107,7 +112,7 @@ int main(int argc, char **argv) {
HTTP2_ERROR_TO_GRPC_STATUS(GRPC_HTTP2_INADEQUATE_SECURITY, before_deadline,
GRPC_STATUS_PERMISSION_DENIED);
const gpr_timespec after_deadline = gpr_inf_past(GPR_CLOCK_MONOTONIC);
const grpc_millis after_deadline = 0;
HTTP2_ERROR_TO_GRPC_STATUS(GRPC_HTTP2_NO_ERROR, after_deadline,
GRPC_STATUS_INTERNAL);
HTTP2_ERROR_TO_GRPC_STATUS(GRPC_HTTP2_PROTOCOL_ERROR, after_deadline,

@ -30,7 +30,7 @@
#define LOG_TEST(x) gpr_log(GPR_INFO, "%s", x)
static void assert_encodes_as(gpr_timespec ts, const char *s) {
static void assert_encodes_as(grpc_millis ts, const char *s) {
char buffer[GRPC_HTTP2_TIMEOUT_ENCODE_MIN_BUFSIZE];
grpc_http2_encode_timeout(ts, buffer);
gpr_log(GPR_INFO, "check '%s' == '%s'", buffer, s);
@ -39,47 +39,38 @@ static void assert_encodes_as(gpr_timespec ts, const char *s) {
void test_encoding(void) {
LOG_TEST("test_encoding");
assert_encodes_as(gpr_time_from_micros(-1, GPR_TIMESPAN), "1n");
assert_encodes_as(gpr_time_from_seconds(-10, GPR_TIMESPAN), "1n");
assert_encodes_as(gpr_time_from_nanos(10, GPR_TIMESPAN), "10n");
assert_encodes_as(gpr_time_from_nanos(999999999, GPR_TIMESPAN), "1S");
assert_encodes_as(gpr_time_from_micros(1, GPR_TIMESPAN), "1u");
assert_encodes_as(gpr_time_from_micros(10, GPR_TIMESPAN), "10u");
assert_encodes_as(gpr_time_from_micros(100, GPR_TIMESPAN), "100u");
assert_encodes_as(gpr_time_from_micros(890, GPR_TIMESPAN), "890u");
assert_encodes_as(gpr_time_from_micros(900, GPR_TIMESPAN), "900u");
assert_encodes_as(gpr_time_from_micros(901, GPR_TIMESPAN), "901u");
assert_encodes_as(gpr_time_from_millis(1, GPR_TIMESPAN), "1m");
assert_encodes_as(gpr_time_from_millis(2, GPR_TIMESPAN), "2m");
assert_encodes_as(gpr_time_from_micros(10001, GPR_TIMESPAN), "10100u");
assert_encodes_as(gpr_time_from_micros(999999, GPR_TIMESPAN), "1S");
assert_encodes_as(gpr_time_from_millis(1000, GPR_TIMESPAN), "1S");
assert_encodes_as(gpr_time_from_millis(2000, GPR_TIMESPAN), "2S");
assert_encodes_as(gpr_time_from_millis(2500, GPR_TIMESPAN), "2500m");
assert_encodes_as(gpr_time_from_millis(59900, GPR_TIMESPAN), "59900m");
assert_encodes_as(gpr_time_from_seconds(50, GPR_TIMESPAN), "50S");
assert_encodes_as(gpr_time_from_seconds(59, GPR_TIMESPAN), "59S");
assert_encodes_as(gpr_time_from_seconds(60, GPR_TIMESPAN), "1M");
assert_encodes_as(gpr_time_from_seconds(80, GPR_TIMESPAN), "80S");
assert_encodes_as(gpr_time_from_seconds(90, GPR_TIMESPAN), "90S");
assert_encodes_as(gpr_time_from_minutes(2, GPR_TIMESPAN), "2M");
assert_encodes_as(gpr_time_from_minutes(20, GPR_TIMESPAN), "20M");
assert_encodes_as(gpr_time_from_hours(1, GPR_TIMESPAN), "1H");
assert_encodes_as(gpr_time_from_hours(10, GPR_TIMESPAN), "10H");
assert_encodes_as(gpr_time_from_seconds(1000000000, GPR_TIMESPAN),
"1000000000S");
assert_encodes_as(-1, "1n");
assert_encodes_as(-10, "1n");
assert_encodes_as(1, "1m");
assert_encodes_as(10, "10m");
assert_encodes_as(100, "100m");
assert_encodes_as(890, "890m");
assert_encodes_as(900, "900m");
assert_encodes_as(901, "901m");
assert_encodes_as(1000, "1S");
assert_encodes_as(2000, "2S");
assert_encodes_as(2500, "2500m");
assert_encodes_as(59900, "59900m");
assert_encodes_as(50000, "50S");
assert_encodes_as(59000, "59S");
assert_encodes_as(60000, "1M");
assert_encodes_as(80000, "80S");
assert_encodes_as(90000, "90S");
assert_encodes_as(120000, "2M");
assert_encodes_as(20 * 60 * GPR_MS_PER_SEC, "20M");
assert_encodes_as(60 * 60 * GPR_MS_PER_SEC, "1H");
assert_encodes_as(10 * 60 * 60 * GPR_MS_PER_SEC, "10H");
}
static void assert_decodes_as(const char *buffer, gpr_timespec expected) {
gpr_timespec got;
static void assert_decodes_as(const char *buffer, grpc_millis expected) {
grpc_millis got;
gpr_log(GPR_INFO, "check decoding '%s'", buffer);
GPR_ASSERT(1 == grpc_http2_decode_timeout(
grpc_slice_from_static_string(buffer), &got));
GPR_ASSERT(0 == gpr_time_cmp(got, expected));
GPR_ASSERT(got == expected);
}
void decode_suite(char ext,
gpr_timespec (*answer)(int64_t x, gpr_clock_type clock)) {
void decode_suite(char ext, grpc_millis (*answer)(int64_t x)) {
long test_vals[] = {1, 12, 123, 1234, 12345, 123456,
1234567, 12345678, 123456789, 98765432, 9876543, 987654,
98765, 9876, 987, 98, 9};
@ -87,41 +78,51 @@ void decode_suite(char ext,
char *input;
for (i = 0; i < GPR_ARRAY_SIZE(test_vals); i++) {
gpr_asprintf(&input, "%ld%c", test_vals[i], ext);
assert_decodes_as(input, answer(test_vals[i], GPR_TIMESPAN));
assert_decodes_as(input, answer(test_vals[i]));
gpr_free(input);
gpr_asprintf(&input, " %ld%c", test_vals[i], ext);
assert_decodes_as(input, answer(test_vals[i], GPR_TIMESPAN));
assert_decodes_as(input, answer(test_vals[i]));
gpr_free(input);
gpr_asprintf(&input, "%ld %c", test_vals[i], ext);
assert_decodes_as(input, answer(test_vals[i], GPR_TIMESPAN));
assert_decodes_as(input, answer(test_vals[i]));
gpr_free(input);
gpr_asprintf(&input, "%ld %c ", test_vals[i], ext);
assert_decodes_as(input, answer(test_vals[i], GPR_TIMESPAN));
assert_decodes_as(input, answer(test_vals[i]));
gpr_free(input);
}
}
static grpc_millis millis_from_nanos(int64_t x) { return x / GPR_NS_PER_MS; }
static grpc_millis millis_from_micros(int64_t x) { return x / GPR_US_PER_MS; }
static grpc_millis millis_from_millis(int64_t x) { return x; }
static grpc_millis millis_from_seconds(int64_t x) { return x * GPR_MS_PER_SEC; }
static grpc_millis millis_from_minutes(int64_t x) {
return x * 60 * GPR_MS_PER_SEC;
}
static grpc_millis millis_from_hours(int64_t x) {
return x * 3600 * GPR_MS_PER_SEC;
}
void test_decoding(void) {
LOG_TEST("test_decoding");
decode_suite('n', gpr_time_from_nanos);
decode_suite('u', gpr_time_from_micros);
decode_suite('m', gpr_time_from_millis);
decode_suite('S', gpr_time_from_seconds);
decode_suite('M', gpr_time_from_minutes);
decode_suite('H', gpr_time_from_hours);
assert_decodes_as("1000000000S",
gpr_time_from_seconds(1000 * 1000 * 1000, GPR_TIMESPAN));
assert_decodes_as("1000000000000000000000u", gpr_inf_future(GPR_TIMESPAN));
assert_decodes_as("1000000001S", gpr_inf_future(GPR_TIMESPAN));
assert_decodes_as("2000000001S", gpr_inf_future(GPR_TIMESPAN));
assert_decodes_as("9999999999S", gpr_inf_future(GPR_TIMESPAN));
decode_suite('n', millis_from_nanos);
decode_suite('u', millis_from_micros);
decode_suite('m', millis_from_millis);
decode_suite('S', millis_from_seconds);
decode_suite('M', millis_from_minutes);
decode_suite('H', millis_from_hours);
assert_decodes_as("1000000000S", millis_from_seconds(1000 * 1000 * 1000));
assert_decodes_as("1000000000000000000000u", GRPC_MILLIS_INF_FUTURE);
assert_decodes_as("1000000001S", GRPC_MILLIS_INF_FUTURE);
assert_decodes_as("2000000001S", GRPC_MILLIS_INF_FUTURE);
assert_decodes_as("9999999999S", GRPC_MILLIS_INF_FUTURE);
}
static void assert_decoding_fails(const char *s) {
gpr_timespec x;
grpc_millis x;
GPR_ASSERT(0 ==
grpc_http2_decode_timeout(grpc_slice_from_static_string(s), &x));
}

@ -563,7 +563,7 @@ static void BM_IsolatedFilter(benchmark::State &state) {
grpc_exec_ctx_flush(&exec_ctx);
grpc_call_stack *call_stack = static_cast<grpc_call_stack *>(
gpr_zalloc(channel_stack->call_stack_size));
gpr_timespec deadline = gpr_inf_future(GPR_CLOCK_MONOTONIC);
grpc_millis deadline = GRPC_MILLIS_INF_FUTURE;
gpr_timespec start_time = gpr_now(GPR_CLOCK_MONOTONIC);
grpc_slice method = grpc_slice_from_static_string("/foo/bar");
grpc_call_final_info final_info;

@ -296,7 +296,7 @@ static void BM_StreamCreateSendInitialMetadataDestroy(benchmark::State &state) {
grpc_metadata_batch b;
grpc_metadata_batch_init(&b);
b.deadline = gpr_inf_future(GPR_CLOCK_MONOTONIC);
b.deadline = GRPC_MILLIS_INF_FUTURE;
std::vector<grpc_mdelem> elems = Metadata::GetElems(f.exec_ctx());
std::vector<grpc_linked_mdelem> storage(elems.size());
for (size_t i = 0; i < elems.size(); i++) {
@ -377,7 +377,7 @@ static void BM_TransportStreamSend(benchmark::State &state) {
grpc_metadata_batch b;
grpc_metadata_batch_init(&b);
b.deadline = gpr_inf_future(GPR_CLOCK_MONOTONIC);
b.deadline = GRPC_MILLIS_INF_FUTURE;
std::vector<grpc_mdelem> elems =
RepresentativeClientInitialMetadata::GetElems(f.exec_ctx());
std::vector<grpc_linked_mdelem> storage(elems.size());
@ -497,7 +497,7 @@ static void BM_TransportStreamRecv(benchmark::State &state) {
grpc_metadata_batch_init(&b);
grpc_metadata_batch b_recv;
grpc_metadata_batch_init(&b_recv);
b.deadline = gpr_inf_future(GPR_CLOCK_MONOTONIC);
b.deadline = GRPC_MILLIS_INF_FUTURE;
std::vector<grpc_mdelem> elems =
RepresentativeClientInitialMetadata::GetElems(f.exec_ctx());
std::vector<grpc_linked_mdelem> storage(elems.size());

@ -70,9 +70,9 @@ static void cq_done_cb(grpc_exec_ctx* exec_ctx, void* done_arg,
/* Queues a completion tag if deadline is > 0.
* Does nothing if deadline is 0 (i.e gpr_time_0(GPR_CLOCK_MONOTONIC)) */
static grpc_error* pollset_work(grpc_exec_ctx* exec_ctx, grpc_pollset* ps,
grpc_pollset_worker** worker, gpr_timespec now,
gpr_timespec deadline) {
if (gpr_time_cmp(deadline, gpr_time_0(GPR_CLOCK_MONOTONIC)) == 0) {
grpc_pollset_worker** worker,
grpc_millis deadline) {
if (deadline == 0) {
gpr_log(GPR_DEBUG, "no-op");
return GRPC_ERROR_NONE;
}

@ -159,39 +159,39 @@ BENCHMARK(BM_ErrorGetPresentInt);
// Fixtures for tests: generate different kinds of errors
class ErrorNone {
public:
gpr_timespec deadline() const { return deadline_; }
grpc_millis deadline() const { return deadline_; }
grpc_error* error() const { return GRPC_ERROR_NONE; }
private:
const gpr_timespec deadline_ = gpr_inf_future(GPR_CLOCK_MONOTONIC);
const grpc_millis deadline_ = GRPC_MILLIS_INF_FUTURE;
};
class ErrorCancelled {
public:
gpr_timespec deadline() const { return deadline_; }
grpc_millis deadline() const { return deadline_; }
grpc_error* error() const { return GRPC_ERROR_CANCELLED; }
private:
const gpr_timespec deadline_ = gpr_inf_future(GPR_CLOCK_MONOTONIC);
const grpc_millis deadline_ = GRPC_MILLIS_INF_FUTURE;
};
class SimpleError {
public:
gpr_timespec deadline() const { return deadline_; }
grpc_millis deadline() const { return deadline_; }
grpc_error* error() const { return error_.get(); }
private:
const gpr_timespec deadline_ = gpr_inf_future(GPR_CLOCK_MONOTONIC);
const grpc_millis deadline_ = GRPC_MILLIS_INF_FUTURE;
ErrorPtr error_{GRPC_ERROR_CREATE_FROM_STATIC_STRING("Error")};
};
class ErrorWithGrpcStatus {
public:
gpr_timespec deadline() const { return deadline_; }
grpc_millis deadline() const { return deadline_; }
grpc_error* error() const { return error_.get(); }
private:
const gpr_timespec deadline_ = gpr_inf_future(GPR_CLOCK_MONOTONIC);
const grpc_millis deadline_ = GRPC_MILLIS_INF_FUTURE;
ErrorPtr error_{grpc_error_set_int(
GRPC_ERROR_CREATE_FROM_STATIC_STRING("Error"), GRPC_ERROR_INT_GRPC_STATUS,
GRPC_STATUS_UNIMPLEMENTED)};
@ -199,11 +199,11 @@ class ErrorWithGrpcStatus {
class ErrorWithHttpError {
public:
gpr_timespec deadline() const { return deadline_; }
grpc_millis deadline() const { return deadline_; }
grpc_error* error() const { return error_.get(); }
private:
const gpr_timespec deadline_ = gpr_inf_future(GPR_CLOCK_MONOTONIC);
const grpc_millis deadline_ = GRPC_MILLIS_INF_FUTURE;
ErrorPtr error_{grpc_error_set_int(
GRPC_ERROR_CREATE_FROM_STATIC_STRING("Error"), GRPC_ERROR_INT_HTTP2_ERROR,
GRPC_HTTP2_COMPRESSION_ERROR)};
@ -211,11 +211,11 @@ class ErrorWithHttpError {
class ErrorWithNestedGrpcStatus {
public:
gpr_timespec deadline() const { return deadline_; }
grpc_millis deadline() const { return deadline_; }
grpc_error* error() const { return error_.get(); }
private:
const gpr_timespec deadline_ = gpr_inf_future(GPR_CLOCK_MONOTONIC);
const grpc_millis deadline_ = GRPC_MILLIS_INF_FUTURE;
ErrorPtr nested_error_{grpc_error_set_int(
GRPC_ERROR_CREATE_FROM_STATIC_STRING("Error"), GRPC_ERROR_INT_GRPC_STATUS,
GRPC_STATUS_UNIMPLEMENTED)};
@ -248,12 +248,14 @@ template <class Fixture>
static void BM_ErrorGetStatus(benchmark::State& state) {
TrackCounters track_counters;
Fixture fixture;
grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
while (state.KeepRunning()) {
grpc_status_code status;
grpc_slice slice;
grpc_error_get_status(fixture.error(), fixture.deadline(), &status, &slice,
NULL);
grpc_error_get_status(&exec_ctx, fixture.error(), fixture.deadline(),
&status, &slice, NULL);
}
grpc_exec_ctx_finish(&exec_ctx);
track_counters.Finish(state);
}
@ -261,11 +263,13 @@ template <class Fixture>
static void BM_ErrorGetStatusCode(benchmark::State& state) {
TrackCounters track_counters;
Fixture fixture;
grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
while (state.KeepRunning()) {
grpc_status_code status;
grpc_error_get_status(fixture.error(), fixture.deadline(), &status, NULL,
NULL);
grpc_error_get_status(&exec_ctx, fixture.error(), fixture.deadline(),
&status, NULL, NULL);
}
grpc_exec_ctx_finish(&exec_ctx);
track_counters.Finish(state);
}
@ -273,11 +277,13 @@ template <class Fixture>
static void BM_ErrorHttpError(benchmark::State& state) {
TrackCounters track_counters;
Fixture fixture;
grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
while (state.KeepRunning()) {
grpc_http2_error_code error;
grpc_error_get_status(fixture.error(), fixture.deadline(), NULL, NULL,
&error);
grpc_error_get_status(&exec_ctx, fixture.error(), fixture.deadline(), NULL,
NULL, &error);
}
grpc_exec_ctx_finish(&exec_ctx);
track_counters.Finish(state);
}

@ -117,11 +117,9 @@ static void BM_PollEmptyPollset(benchmark::State& state) {
gpr_mu* mu;
grpc_pollset_init(ps, &mu);
grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
gpr_timespec now = gpr_time_0(GPR_CLOCK_MONOTONIC);
gpr_timespec deadline = gpr_inf_past(GPR_CLOCK_MONOTONIC);
gpr_mu_lock(mu);
while (state.KeepRunning()) {
GRPC_ERROR_UNREF(grpc_pollset_work(&exec_ctx, ps, NULL, now, deadline));
GRPC_ERROR_UNREF(grpc_pollset_work(&exec_ctx, ps, NULL, 0));
}
grpc_closure shutdown_ps_closure;
GRPC_CLOSURE_INIT(&shutdown_ps_closure, shutdown_ps, ps,
@ -223,8 +221,6 @@ static void BM_SingleThreadPollOneFd(benchmark::State& state) {
gpr_mu* mu;
grpc_pollset_init(ps, &mu);
grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
gpr_timespec now = gpr_time_0(GPR_CLOCK_MONOTONIC);
gpr_timespec deadline = gpr_inf_future(GPR_CLOCK_MONOTONIC);
grpc_wakeup_fd wakeup_fd;
GRPC_ERROR_UNREF(grpc_wakeup_fd_init(&wakeup_fd));
grpc_fd* wakeup = grpc_fd_create(wakeup_fd.read_fd, "wakeup_read");
@ -245,7 +241,8 @@ static void BM_SingleThreadPollOneFd(benchmark::State& state) {
grpc_fd_notify_on_read(&exec_ctx, wakeup, continue_closure);
gpr_mu_lock(mu);
while (!done) {
GRPC_ERROR_UNREF(grpc_pollset_work(&exec_ctx, ps, NULL, now, deadline));
GRPC_ERROR_UNREF(
grpc_pollset_work(&exec_ctx, ps, NULL, GRPC_MILLIS_INF_FUTURE));
}
grpc_fd_orphan(&exec_ctx, wakeup, NULL, NULL, "done");
wakeup_fd.read_fd = 0;

Loading…
Cancel
Save