Merge branch 'master' into cq_create_api_changes

pull/9972/head
Sree Kuchibhotla 8 years ago
commit 33f4c6d04a
  1. 19
      doc/statuscodes.md
  2. 3
      include/grpc/support/alloc.h
  3. 4
      src/core/lib/channel/message_size_filter.c
  4. 11
      src/core/lib/iomgr/closure.c
  5. 4
      src/core/lib/iomgr/closure.h
  6. 6
      src/core/lib/iomgr/combiner.c
  7. 3
      src/core/lib/iomgr/ev_epoll_linux.c
  8. 6
      src/core/lib/iomgr/exec_ctx.c
  9. 6
      src/core/lib/iomgr/executor.c
  10. 4
      src/core/lib/iomgr/sockaddr_utils.c
  11. 6
      src/core/lib/slice/slice.c
  12. 1
      src/core/lib/transport/pid_controller.c
  13. 4
      test/core/end2end/tests/max_message_length.c
  14. 2
      tools/internal_ci/linux/sanitizer/grpc_cpp_asan.sh
  15. 2
      tools/internal_ci/linux/sanitizer/grpc_cpp_tsan.sh

@ -1,9 +1,20 @@
# Status codes and their use in gRPC # Status codes and their use in gRPC
gRPC uses a set of well defined status codes as part of the RPC API. All RPCs started at a client return a `status` object composed of an integer `code` and a string `message`. The server-side can choose the status it returns for a given RPC. gRPC uses a set of well defined status codes as part of the RPC API. All
RPCs started at a client return a `status` object composed of an integer
`code` and a string `message`. The server-side can choose the status it
returns for a given RPC.
The gRPC client and server-side implementations may also generate and return `status` on their own when errors happen. The gRPC client and server-side implementations may also generate and
Only a subset of the pre-defined status codes are generated by the gRPC libraries. The following table lists these codes and summarizes the situations in which they are generated, either by the client or the server-side library implementation. return `status` on their own when errors happen. Only a subset of
the pre-defined status codes are generated by the gRPC libraries. This
allows applications to be sure that any other code it sees was actually
returned by the application (although it is also possible for the
server-side to return one of the codes generated by the gRPC libraries).
The following table lists the codes that may be returned by the gRPC
libraries (on either the client-side or server-side) and summarizes the
situations in which they are generated.
| Case | Code | Generated at Client or Server | | Case | Code | Generated at Client or Server |
| ------------- |:-------------| :-----:| | ------------- |:-------------| :-----:|
@ -26,7 +37,7 @@ Only a subset of the pre-defined status codes are generated by the gRPC librarie
| Response cardinality violation (method requires exactly one response but server sent some other number of responses) | UNIMPLEMENTED | Client| | Response cardinality violation (method requires exactly one response but server sent some other number of responses) | UNIMPLEMENTED | Client|
| Error parsing response proto | INTERNAL | Client| | Error parsing response proto | INTERNAL | Client|
| Error parsing request proto | INTERNAL | Server| | Error parsing request proto | INTERNAL | Server|
| Sent or received message was larger than configured limit | RESOURCE_EXHAUSTED | Both |
The following status codes are never generated by the library: The following status codes are never generated by the library:
- INVALID_ARGUMENT - INVALID_ARGUMENT

@ -68,7 +68,8 @@ GPRAPI void gpr_free_aligned(void *ptr);
/** Request the family of allocation functions in \a functions be used. NOTE /** Request the family of allocation functions in \a functions be used. NOTE
* that this request will be honored in a *best effort* basis and that no * that this request will be honored in a *best effort* basis and that no
* guarantees are made about the default functions (eg, malloc) being called. */ * guarantees are made about the default functions (eg, malloc) being called.
* The functions.free_fn implementation must be a no-op for NULL input. */
GPRAPI void gpr_set_allocation_functions(gpr_allocation_functions functions); GPRAPI void gpr_set_allocation_functions(gpr_allocation_functions functions);
/** Return the family of allocation functions currently in effect. */ /** Return the family of allocation functions currently in effect. */

@ -122,7 +122,7 @@ static void recv_message_ready(grpc_exec_ctx* exec_ctx, void* user_data,
(*calld->recv_message)->length, calld->max_recv_size); (*calld->recv_message)->length, calld->max_recv_size);
grpc_error* new_error = grpc_error_set_int( grpc_error* new_error = grpc_error_set_int(
GRPC_ERROR_CREATE_FROM_COPIED_STRING(message_string), GRPC_ERROR_CREATE_FROM_COPIED_STRING(message_string),
GRPC_ERROR_INT_GRPC_STATUS, GRPC_STATUS_INVALID_ARGUMENT); GRPC_ERROR_INT_GRPC_STATUS, GRPC_STATUS_RESOURCE_EXHAUSTED);
if (error == GRPC_ERROR_NONE) { if (error == GRPC_ERROR_NONE) {
error = new_error; error = new_error;
} else { } else {
@ -152,7 +152,7 @@ static void start_transport_stream_op_batch(
exec_ctx, op, exec_ctx, op,
grpc_error_set_int(GRPC_ERROR_CREATE_FROM_COPIED_STRING(message_string), grpc_error_set_int(GRPC_ERROR_CREATE_FROM_COPIED_STRING(message_string),
GRPC_ERROR_INT_GRPC_STATUS, GRPC_ERROR_INT_GRPC_STATUS,
GRPC_STATUS_INVALID_ARGUMENT)); GRPC_STATUS_RESOURCE_EXHAUSTED));
gpr_free(message_string); gpr_free(message_string);
return; return;
} }

@ -45,6 +45,9 @@ grpc_closure *grpc_closure_init(grpc_closure *closure, grpc_iomgr_cb_func cb,
closure->cb = cb; closure->cb = cb;
closure->cb_arg = cb_arg; closure->cb_arg = cb_arg;
closure->scheduler = scheduler; closure->scheduler = scheduler;
#ifndef NDEBUG
closure->scheduled = false;
#endif
return closure; return closure;
} }
@ -137,6 +140,10 @@ void grpc_closure_sched(grpc_exec_ctx *exec_ctx, grpc_closure *c,
grpc_error *error) { grpc_error *error) {
GPR_TIMER_BEGIN("grpc_closure_sched", 0); GPR_TIMER_BEGIN("grpc_closure_sched", 0);
if (c != NULL) { if (c != NULL) {
#ifndef NDEBUG
GPR_ASSERT(!c->scheduled);
c->scheduled = true;
#endif
assert(c->cb); assert(c->cb);
c->scheduler->vtable->sched(exec_ctx, c, error); c->scheduler->vtable->sched(exec_ctx, c, error);
} else { } else {
@ -149,6 +156,10 @@ void grpc_closure_list_sched(grpc_exec_ctx *exec_ctx, grpc_closure_list *list) {
grpc_closure *c = list->head; grpc_closure *c = list->head;
while (c != NULL) { while (c != NULL) {
grpc_closure *next = c->next_data.next; grpc_closure *next = c->next_data.next;
#ifndef NDEBUG
GPR_ASSERT(!c->scheduled);
c->scheduled = true;
#endif
assert(c->cb); assert(c->cb);
c->scheduler->vtable->sched(exec_ctx, c, c->error_data.error); c->scheduler->vtable->sched(exec_ctx, c, c->error_data.error);
c = next; c = next;

@ -99,6 +99,10 @@ struct grpc_closure {
grpc_error *error; grpc_error *error;
uintptr_t scratch; uintptr_t scratch;
} error_data; } error_data;
#ifndef NDEBUG
bool scheduled;
#endif
}; };
/** Initializes \a closure with \a cb and \a cb_arg. Returns \a closure. */ /** Initializes \a closure with \a cb and \a cb_arg. Returns \a closure. */

@ -319,6 +319,9 @@ bool grpc_combiner_continue_exec_ctx(grpc_exec_ctx *exec_ctx) {
GPR_TIMER_BEGIN("combiner.exec1", 0); GPR_TIMER_BEGIN("combiner.exec1", 0);
grpc_closure *cl = (grpc_closure *)n; grpc_closure *cl = (grpc_closure *)n;
error_data err = unpack_error_data(cl->error_data.scratch); error_data err = unpack_error_data(cl->error_data.scratch);
#ifndef NDEBUG
cl->scheduled = false;
#endif
cl->cb(exec_ctx, cl->cb_arg, err.error); cl->cb(exec_ctx, cl->cb_arg, err.error);
if (err.covered_by_poller) { if (err.covered_by_poller) {
gpr_atm_no_barrier_fetch_add(&lock->elements_covered_by_poller, -1); gpr_atm_no_barrier_fetch_add(&lock->elements_covered_by_poller, -1);
@ -337,6 +340,9 @@ bool grpc_combiner_continue_exec_ctx(grpc_exec_ctx *exec_ctx) {
gpr_log(GPR_DEBUG, "C:%p execute_final[%d] c=%p", lock, loops, c)); gpr_log(GPR_DEBUG, "C:%p execute_final[%d] c=%p", lock, loops, c));
grpc_closure *next = c->next_data.next; grpc_closure *next = c->next_data.next;
grpc_error *error = c->error_data.error; grpc_error *error = c->error_data.error;
#ifndef NDEBUG
c->scheduled = false;
#endif
c->cb(exec_ctx, c->cb_arg, error); c->cb(exec_ctx, c->cb_arg, error);
GRPC_ERROR_UNREF(error); GRPC_ERROR_UNREF(error);
c = next; c = next;

@ -1348,6 +1348,9 @@ static bool maybe_do_workqueue_work(grpc_exec_ctx *exec_ctx,
} }
grpc_closure *c = (grpc_closure *)n; grpc_closure *c = (grpc_closure *)n;
grpc_error *error = c->error_data.error; grpc_error *error = c->error_data.error;
#ifndef NDEBUG
c->scheduled = false;
#endif
c->cb(exec_ctx, c->cb_arg, error); c->cb(exec_ctx, c->cb_arg, error);
GRPC_ERROR_UNREF(error); GRPC_ERROR_UNREF(error);
return true; return true;

@ -73,6 +73,9 @@ bool grpc_exec_ctx_flush(grpc_exec_ctx *exec_ctx) {
grpc_closure *next = c->next_data.next; grpc_closure *next = c->next_data.next;
grpc_error *error = c->error_data.error; grpc_error *error = c->error_data.error;
did_something = true; did_something = true;
#ifndef NDEBUG
c->scheduled = false;
#endif
c->cb(exec_ctx, c->cb_arg, error); c->cb(exec_ctx, c->cb_arg, error);
GRPC_ERROR_UNREF(error); GRPC_ERROR_UNREF(error);
c = next; c = next;
@ -93,6 +96,9 @@ void grpc_exec_ctx_finish(grpc_exec_ctx *exec_ctx) {
static void exec_ctx_run(grpc_exec_ctx *exec_ctx, grpc_closure *closure, static void exec_ctx_run(grpc_exec_ctx *exec_ctx, grpc_closure *closure,
grpc_error *error) { grpc_error *error) {
#ifndef NDEBUG
closure->scheduled = false;
#endif
closure->cb(exec_ctx, closure->cb_arg, error); closure->cb(exec_ctx, closure->cb_arg, error);
GRPC_ERROR_UNREF(error); GRPC_ERROR_UNREF(error);
} }

@ -83,6 +83,9 @@ static void closure_exec_thread_func(void *ignored) {
while (c != NULL) { while (c != NULL) {
grpc_closure *next = c->next_data.next; grpc_closure *next = c->next_data.next;
grpc_error *error = c->error_data.error; grpc_error *error = c->error_data.error;
#ifndef NDEBUG
c->scheduled = false;
#endif
c->cb(&exec_ctx, c->cb_arg, error); c->cb(&exec_ctx, c->cb_arg, error);
GRPC_ERROR_UNREF(error); GRPC_ERROR_UNREF(error);
c = next; c = next;
@ -146,6 +149,9 @@ void grpc_executor_shutdown(grpc_exec_ctx *exec_ctx) {
while (c != NULL) { while (c != NULL) {
grpc_closure *next = c->next_data.next; grpc_closure *next = c->next_data.next;
grpc_error *error = c->error_data.error; grpc_error *error = c->error_data.error;
#ifndef NDEBUG
c->scheduled = false;
#endif
c->cb(exec_ctx, c->cb_arg, error); c->cb(exec_ctx, c->cb_arg, error);
GRPC_ERROR_UNREF(error); GRPC_ERROR_UNREF(error);
c = next; c = next;

@ -55,7 +55,9 @@ int grpc_sockaddr_is_v4mapped(const grpc_resolved_address *resolved_addr,
GPR_ASSERT(resolved_addr != resolved_addr4_out); GPR_ASSERT(resolved_addr != resolved_addr4_out);
const struct sockaddr *addr = (const struct sockaddr *)resolved_addr->addr; const struct sockaddr *addr = (const struct sockaddr *)resolved_addr->addr;
struct sockaddr_in *addr4_out = struct sockaddr_in *addr4_out =
(struct sockaddr_in *)resolved_addr4_out->addr; resolved_addr4_out == NULL
? NULL
: (struct sockaddr_in *)resolved_addr4_out->addr;
if (addr->sa_family == AF_INET6) { if (addr->sa_family == AF_INET6) {
const struct sockaddr_in6 *addr6 = (const struct sockaddr_in6 *)addr; const struct sockaddr_in6 *addr6 = (const struct sockaddr_in6 *)addr;
if (memcmp(addr6->sin6_addr.s6_addr, kV4MappedPrefix, if (memcmp(addr6->sin6_addr.s6_addr, kV4MappedPrefix,

@ -197,6 +197,7 @@ grpc_slice grpc_slice_new_with_len(void *p, size_t len,
} }
grpc_slice grpc_slice_from_copied_buffer(const char *source, size_t length) { grpc_slice grpc_slice_from_copied_buffer(const char *source, size_t length) {
if (length == 0) return grpc_empty_slice();
grpc_slice slice = grpc_slice_malloc(length); grpc_slice slice = grpc_slice_malloc(length);
memcpy(GRPC_SLICE_START_PTR(slice), source, length); memcpy(GRPC_SLICE_START_PTR(slice), source, length);
return slice; return slice;
@ -382,8 +383,9 @@ grpc_slice grpc_slice_split_head(grpc_slice *source, size_t split) {
} }
int grpc_slice_default_eq_impl(grpc_slice a, grpc_slice b) { int grpc_slice_default_eq_impl(grpc_slice a, grpc_slice b) {
return GRPC_SLICE_LENGTH(a) == GRPC_SLICE_LENGTH(b) && if (GRPC_SLICE_LENGTH(a) != GRPC_SLICE_LENGTH(b)) return false;
0 == memcmp(GRPC_SLICE_START_PTR(a), GRPC_SLICE_START_PTR(b), if (GRPC_SLICE_LENGTH(a) == 0) return true;
return 0 == memcmp(GRPC_SLICE_START_PTR(a), GRPC_SLICE_START_PTR(b),
GRPC_SLICE_LENGTH(a)); GRPC_SLICE_LENGTH(a));
} }

@ -49,6 +49,7 @@ void grpc_pid_controller_reset(grpc_pid_controller *pid_controller) {
double grpc_pid_controller_update(grpc_pid_controller *pid_controller, double grpc_pid_controller_update(grpc_pid_controller *pid_controller,
double error, double dt) { double error, double dt) {
if (dt == 0) return pid_controller->last_control_value;
/* integrate error using the trapezoid rule */ /* integrate error using the trapezoid rule */
pid_controller->error_integral += pid_controller->error_integral +=
dt * (pid_controller->last_error + error) * 0.5; dt * (pid_controller->last_error + error) * 0.5;

@ -274,7 +274,7 @@ static void test_max_message_length_on_request(grpc_end2end_test_config config,
GPR_ASSERT(was_cancelled == 1); GPR_ASSERT(was_cancelled == 1);
done: done:
GPR_ASSERT(status == GRPC_STATUS_INVALID_ARGUMENT); GPR_ASSERT(status == GRPC_STATUS_RESOURCE_EXHAUSTED);
GPR_ASSERT( GPR_ASSERT(
grpc_slice_str_cmp( grpc_slice_str_cmp(
details, send_limit details, send_limit
@ -468,7 +468,7 @@ static void test_max_message_length_on_response(grpc_end2end_test_config config,
GPR_ASSERT(0 == GPR_ASSERT(0 ==
grpc_slice_str_cmp(call_details.host, "foo.test.google.fr:1234")); grpc_slice_str_cmp(call_details.host, "foo.test.google.fr:1234"));
GPR_ASSERT(status == GRPC_STATUS_INVALID_ARGUMENT); GPR_ASSERT(status == GRPC_STATUS_RESOURCE_EXHAUSTED);
GPR_ASSERT( GPR_ASSERT(
grpc_slice_str_cmp( grpc_slice_str_cmp(
details, send_limit details, send_limit

@ -37,4 +37,4 @@ git submodule update --init
# download docker images from dockerhub # download docker images from dockerhub
export DOCKERHUB_ORGANIZATION=grpctesting export DOCKERHUB_ORGANIZATION=grpctesting
tools/run_tests/run_tests_matrix.py -f cpp asan tools/run_tests/run_tests_matrix.py -f c++ asan

@ -37,4 +37,4 @@ git submodule update --init
# download docker images from dockerhub # download docker images from dockerhub
export DOCKERHUB_ORGANIZATION=grpctesting export DOCKERHUB_ORGANIZATION=grpctesting
tools/run_tests/run_tests_matrix.py -f cpp tsan tools/run_tests/run_tests_matrix.py -f c++ tsan

Loading…
Cancel
Save