diff options
Diffstat (limited to 'src/core/lib/iomgr')
-rw-r--r-- | src/core/lib/iomgr/closure.c | 1 | ||||
-rw-r--r-- | src/core/lib/iomgr/closure.h | 1 | ||||
-rw-r--r-- | src/core/lib/iomgr/combiner.c | 12 | ||||
-rw-r--r-- | src/core/lib/iomgr/error.c | 154 | ||||
-rw-r--r-- | src/core/lib/iomgr/error.h | 13 | ||||
-rw-r--r-- | src/core/lib/iomgr/error_internal.h | 54 | ||||
-rw-r--r-- | src/core/lib/iomgr/ev_epoll_linux.c | 2 | ||||
-rw-r--r-- | src/core/lib/iomgr/ev_posix.c | 2 | ||||
-rw-r--r-- | src/core/lib/iomgr/exec_ctx.c | 17 | ||||
-rw-r--r-- | src/core/lib/iomgr/exec_ctx.h | 25 | ||||
-rw-r--r-- | src/core/lib/iomgr/executor.c | 4 | ||||
-rw-r--r-- | src/core/lib/iomgr/load_file.c | 2 | ||||
-rw-r--r-- | src/core/lib/iomgr/resource_quota.c | 8 | ||||
-rw-r--r-- | src/core/lib/iomgr/tcp_client_posix.c | 2 | ||||
-rw-r--r-- | src/core/lib/iomgr/tcp_posix.c | 4 | ||||
-rw-r--r-- | src/core/lib/iomgr/tcp_server_windows.c | 2 | ||||
-rw-r--r-- | src/core/lib/iomgr/tcp_uv.c | 3 |
17 files changed, 167 insertions, 139 deletions
diff --git a/src/core/lib/iomgr/closure.c b/src/core/lib/iomgr/closure.c index da0ec878a3..8e4efd3370 100644 --- a/src/core/lib/iomgr/closure.c +++ b/src/core/lib/iomgr/closure.c @@ -34,6 +34,7 @@ #include "src/core/lib/iomgr/closure.h" #include <grpc/support/alloc.h> +#include <grpc/support/log.h> #include "src/core/lib/profiling/timers.h" diff --git a/src/core/lib/iomgr/closure.h b/src/core/lib/iomgr/closure.h index ee386fbc76..6748b21e59 100644 --- a/src/core/lib/iomgr/closure.h +++ b/src/core/lib/iomgr/closure.h @@ -66,6 +66,7 @@ typedef struct grpc_closure_scheduler_vtable { grpc_error *error); void (*sched)(grpc_exec_ctx *exec_ctx, grpc_closure *closure, grpc_error *error); + const char *name; } grpc_closure_scheduler_vtable; /** Abstract type that can schedule closures for execution */ diff --git a/src/core/lib/iomgr/combiner.c b/src/core/lib/iomgr/combiner.c index c26a73b2b7..ba6c7087a9 100644 --- a/src/core/lib/iomgr/combiner.c +++ b/src/core/lib/iomgr/combiner.c @@ -86,13 +86,17 @@ static void combiner_finally_exec_covered(grpc_exec_ctx *exec_ctx, grpc_error *error); static const grpc_closure_scheduler_vtable scheduler_uncovered = { - combiner_exec_uncovered, combiner_exec_uncovered}; + combiner_exec_uncovered, combiner_exec_uncovered, + "combiner:immediately:uncovered"}; static const grpc_closure_scheduler_vtable scheduler_covered = { - combiner_exec_covered, combiner_exec_covered}; + combiner_exec_covered, combiner_exec_covered, + "combiner:immediately:covered"}; static const grpc_closure_scheduler_vtable finally_scheduler_uncovered = { - combiner_finally_exec_uncovered, combiner_finally_exec_uncovered}; + combiner_finally_exec_uncovered, combiner_finally_exec_uncovered, + "combiner:finally:uncovered"}; static const grpc_closure_scheduler_vtable finally_scheduler_covered = { - combiner_finally_exec_covered, combiner_finally_exec_covered}; + combiner_finally_exec_covered, combiner_finally_exec_covered, + "combiner:finally:covered"}; static void offload(grpc_exec_ctx *exec_ctx, void *arg, grpc_error *error); diff --git a/src/core/lib/iomgr/error.c b/src/core/lib/iomgr/error.c index f6bb3a0477..dbe5b139f9 100644 --- a/src/core/lib/iomgr/error.c +++ b/src/core/lib/iomgr/error.c @@ -33,13 +33,10 @@ #include "src/core/lib/iomgr/error.h" -#include <inttypes.h> -#include <stdbool.h> #include <string.h> #include <grpc/status.h> #include <grpc/support/alloc.h> -#include <grpc/support/avl.h> #include <grpc/support/log.h> #include <grpc/support/string_util.h> #include <grpc/support/useful.h> @@ -48,6 +45,7 @@ #include <grpc/support/log_windows.h> #endif +#include "src/core/lib/iomgr/error_internal.h" #include "src/core/lib/profiling/timers.h" static void destroy_integer(void *key) {} @@ -128,6 +126,10 @@ static const char *error_int_name(grpc_error_ints key) { static const char *error_str_name(grpc_error_strs key) { switch (key) { + case GRPC_ERROR_STR_KEY: + return "key"; + case GRPC_ERROR_STR_VALUE: + return "value"; case GRPC_ERROR_STR_DESCRIPTION: return "description"; case GRPC_ERROR_STR_OS_ERROR: @@ -160,16 +162,7 @@ static const char *error_time_name(grpc_error_times key) { GPR_UNREACHABLE_CODE(return "unknown"); } -struct grpc_error { - gpr_refcount refs; - gpr_avl ints; - gpr_avl strs; - gpr_avl times; - gpr_avl errs; - uintptr_t next_err; -}; - -static bool is_special(grpc_error *err) { +bool grpc_error_is_special(grpc_error *err) { return err == GRPC_ERROR_NONE || err == GRPC_ERROR_OOM || err == GRPC_ERROR_CANCELLED; } @@ -177,7 +170,7 @@ static bool is_special(grpc_error *err) { #ifdef GRPC_ERROR_REFCOUNT_DEBUG grpc_error *grpc_error_ref(grpc_error *err, const char *file, int line, const char *func) { - if (is_special(err)) return err; + if (grpc_error_is_special(err)) return err; gpr_log(GPR_DEBUG, "%p: %" PRIdPTR " -> %" PRIdPTR " [%s:%d %s]", err, err->refs.count, err->refs.count + 1, file, line, func); gpr_ref(&err->refs); @@ -185,25 +178,26 @@ grpc_error *grpc_error_ref(grpc_error *err, const char *file, int line, } #else grpc_error *grpc_error_ref(grpc_error *err) { - if (is_special(err)) return err; + if (grpc_error_is_special(err)) return err; gpr_ref(&err->refs); return err; } #endif static void error_destroy(grpc_error *err) { - GPR_ASSERT(!is_special(err)); + GPR_ASSERT(!grpc_error_is_special(err)); gpr_avl_unref(err->ints); gpr_avl_unref(err->strs); gpr_avl_unref(err->errs); gpr_avl_unref(err->times); + gpr_free((void *)gpr_atm_acq_load(&err->error_string)); gpr_free(err); } #ifdef GRPC_ERROR_REFCOUNT_DEBUG void grpc_error_unref(grpc_error *err, const char *file, int line, const char *func) { - if (is_special(err)) return; + if (grpc_error_is_special(err)) return; gpr_log(GPR_DEBUG, "%p: %" PRIdPTR " -> %" PRIdPTR " [%s:%d %s]", err, err->refs.count, err->refs.count - 1, file, line, func); if (gpr_unref(&err->refs)) { @@ -212,7 +206,7 @@ void grpc_error_unref(grpc_error *err, const char *file, int line, } #else void grpc_error_unref(grpc_error *err) { - if (is_special(err)) return; + if (grpc_error_is_special(err)) return; if (gpr_unref(&err->refs)) { error_destroy(err); } @@ -247,6 +241,7 @@ grpc_error *grpc_error_create(const char *file, int line, const char *desc, err->times = gpr_avl_add(gpr_avl_create(&avl_vtable_times), (void *)(uintptr_t)GRPC_ERROR_TIME_CREATED, box_time(gpr_now(GPR_CLOCK_REALTIME))); + gpr_atm_no_barrier_store(&err->error_string, 0); gpr_ref_init(&err->refs, 1); GPR_TIMER_END("grpc_error_create", 0); return err; @@ -255,9 +250,10 @@ grpc_error *grpc_error_create(const char *file, int line, const char *desc, static grpc_error *copy_error_and_unref(grpc_error *in) { GPR_TIMER_BEGIN("copy_error_and_unref", 0); grpc_error *out; - if (is_special(in)) { + if (grpc_error_is_special(in)) { if (in == GRPC_ERROR_NONE) - out = GRPC_ERROR_CREATE("no error"); + out = grpc_error_set_int(GRPC_ERROR_CREATE("no error"), + GRPC_ERROR_INT_GRPC_STATUS, GRPC_STATUS_OK); else if (in == GRPC_ERROR_OOM) out = GRPC_ERROR_CREATE("oom"); else if (in == GRPC_ERROR_CANCELLED) @@ -275,6 +271,7 @@ static grpc_error *copy_error_and_unref(grpc_error *in) { out->strs = gpr_avl_ref(in->strs); out->errs = gpr_avl_ref(in->errs); out->times = gpr_avl_ref(in->times); + gpr_atm_no_barrier_store(&out->error_string, 0); out->next_err = in->next_err; gpr_ref_init(&out->refs, 1); GRPC_ERROR_UNREF(in); @@ -292,14 +289,29 @@ grpc_error *grpc_error_set_int(grpc_error *src, grpc_error_ints which, return new; } +typedef struct { + grpc_error *error; + grpc_status_code code; + const char *msg; +} special_error_status_map; +static special_error_status_map error_status_map[] = { + {GRPC_ERROR_NONE, GRPC_STATUS_OK, NULL}, + {GRPC_ERROR_CANCELLED, GRPC_STATUS_CANCELLED, "Cancelled"}, + {GRPC_ERROR_OOM, GRPC_STATUS_RESOURCE_EXHAUSTED, "Out of memory"}, +}; + bool grpc_error_get_int(grpc_error *err, grpc_error_ints which, intptr_t *p) { GPR_TIMER_BEGIN("grpc_error_get_int", 0); void *pp; - if (is_special(err)) { - if (err == GRPC_ERROR_CANCELLED && which == GRPC_ERROR_INT_GRPC_STATUS) { - *p = GRPC_STATUS_CANCELLED; - GPR_TIMER_END("grpc_error_get_int", 0); - return true; + if (grpc_error_is_special(err)) { + if (which == GRPC_ERROR_INT_GRPC_STATUS) { + for (size_t i = 0; i < GPR_ARRAY_SIZE(error_status_map); i++) { + if (error_status_map[i].error == err) { + if (p != NULL) *p = error_status_map[i].code; + GPR_TIMER_END("grpc_error_get_int", 0); + return true; + } + } } GPR_TIMER_END("grpc_error_get_int", 0); return false; @@ -324,66 +336,17 @@ grpc_error *grpc_error_set_str(grpc_error *src, grpc_error_strs which, } const char *grpc_error_get_str(grpc_error *err, grpc_error_strs which) { - if (is_special(err)) return NULL; - return gpr_avl_get(err->strs, (void *)(uintptr_t)which); -} - -typedef struct { - grpc_error *error; - grpc_status_code code; - const char *msg; -} special_error_status_map; -static special_error_status_map error_status_map[] = { - {GRPC_ERROR_NONE, GRPC_STATUS_OK, ""}, - {GRPC_ERROR_CANCELLED, GRPC_STATUS_CANCELLED, "RPC cancelled"}, - {GRPC_ERROR_OOM, GRPC_STATUS_RESOURCE_EXHAUSTED, "Out of memory"}, -}; - -static grpc_error *recursively_find_error_with_status(grpc_error *error, - intptr_t *status) { - // If the error itself has a status code, return it. - if (grpc_error_get_int(error, GRPC_ERROR_INT_GRPC_STATUS, status)) { - return error; - } - // Otherwise, search through its children. - intptr_t key = 0; - while (true) { - grpc_error *child_error = gpr_avl_get(error->errs, (void *)key++); - if (child_error == NULL) break; - grpc_error *result = - recursively_find_error_with_status(child_error, status); - if (result != NULL) return result; - } - return NULL; -} - -void grpc_error_get_status(grpc_error *error, grpc_status_code *code, - const char **msg) { - // Handle special errors via the static map. - for (size_t i = 0; i < GPR_ARRAY_SIZE(error_status_map); ++i) { - if (error == error_status_map[i].error) { - *code = error_status_map[i].code; - *msg = error_status_map[i].msg; - return; + if (grpc_error_is_special(err)) { + if (which == GRPC_ERROR_STR_GRPC_MESSAGE) { + for (size_t i = 0; i < GPR_ARRAY_SIZE(error_status_map); i++) { + if (error_status_map[i].error == err) { + return error_status_map[i].msg; + } + } } + return NULL; } - // Populate code. - // Start with the parent error and recurse through the tree of children - // until we find the first one that has a status code. - intptr_t status = GRPC_STATUS_UNKNOWN; // Default in case we don't find one. - grpc_error *found_error = recursively_find_error_with_status(error, &status); - *code = (grpc_status_code)status; - // Now populate msg. - // If we found an error with a status code above, use that; otherwise, - // fall back to using the parent error. - if (found_error == NULL) found_error = error; - // If the error has a status message, use it. Otherwise, fall back to - // the error description. - *msg = grpc_error_get_str(found_error, GRPC_ERROR_STR_GRPC_MESSAGE); - if (*msg == NULL) { - *msg = grpc_error_get_str(found_error, GRPC_ERROR_STR_DESCRIPTION); - if (*msg == NULL) *msg = "uknown error"; // Just in case. - } + return gpr_avl_get(err->strs, (void *)(uintptr_t)which); } grpc_error *grpc_error_add_child(grpc_error *src, grpc_error *child) { @@ -535,7 +498,6 @@ static void add_errs(gpr_avl_node *n, char **s, size_t *sz, size_t *cap, *first = false; const char *e = grpc_error_string(n->value); append_str(e, s, sz, cap); - grpc_error_free_string(e); add_errs(n->right, s, sz, cap, first); } @@ -557,7 +519,7 @@ static int cmp_kvs(const void *a, const void *b) { return strcmp(ka->key, kb->key); } -static const char *finish_kvs(kv_pairs *kvs) { +static char *finish_kvs(kv_pairs *kvs) { char *s = NULL; size_t sz = 0; size_t cap = 0; @@ -578,19 +540,18 @@ static const char *finish_kvs(kv_pairs *kvs) { return s; } -void grpc_error_free_string(const char *str) { - if (str == no_error_string) return; - if (str == oom_error_string) return; - if (str == cancelled_error_string) return; - gpr_free((char *)str); -} - const char *grpc_error_string(grpc_error *err) { GPR_TIMER_BEGIN("grpc_error_string", 0); if (err == GRPC_ERROR_NONE) return no_error_string; if (err == GRPC_ERROR_OOM) return oom_error_string; if (err == GRPC_ERROR_CANCELLED) return cancelled_error_string; + void *p = (void *)gpr_atm_acq_load(&err->error_string); + if (p != NULL) { + GPR_TIMER_END("grpc_error_string", 0); + return p; + } + kv_pairs kvs; memset(&kvs, 0, sizeof(kvs)); @@ -603,7 +564,13 @@ const char *grpc_error_string(grpc_error *err) { qsort(kvs.kvs, kvs.num_kvs, sizeof(kv_pair), cmp_kvs); - const char *out = finish_kvs(&kvs); + char *out = finish_kvs(&kvs); + + if (!gpr_atm_rel_cas(&err->error_string, 0, (gpr_atm)out)) { + gpr_free(out); + out = (char *)gpr_atm_no_barrier_load(&err->error_string); + } + GPR_TIMER_END("grpc_error_string", 0); return out; } @@ -638,7 +605,6 @@ bool grpc_log_if_error(const char *what, grpc_error *error, const char *file, if (error == GRPC_ERROR_NONE) return true; const char *msg = grpc_error_string(error); gpr_log(file, line, GPR_LOG_SEVERITY_ERROR, "%s: %s", what, msg); - grpc_error_free_string(msg); GRPC_ERROR_UNREF(error); return false; } diff --git a/src/core/lib/iomgr/error.h b/src/core/lib/iomgr/error.h index f3f3b80a09..ffacdac393 100644 --- a/src/core/lib/iomgr/error.h +++ b/src/core/lib/iomgr/error.h @@ -124,7 +124,11 @@ typedef enum { /// filename that we were trying to read/write when this error occurred GRPC_ERROR_STR_FILENAME, /// which data was queued for writing when the error occurred - GRPC_ERROR_STR_QUEUED_BUFFERS + GRPC_ERROR_STR_QUEUED_BUFFERS, + /// key associated with the error + GRPC_ERROR_STR_KEY, + /// value associated with the error + GRPC_ERROR_STR_VALUE, } grpc_error_strs; typedef enum { @@ -141,7 +145,6 @@ typedef enum { #define GRPC_ERROR_CANCELLED ((grpc_error *)4) const char *grpc_error_string(grpc_error *error); -void grpc_error_free_string(const char *str); /// Create an error - but use GRPC_ERROR_CREATE instead grpc_error *grpc_error_create(const char *file, int line, const char *desc, @@ -189,12 +192,6 @@ grpc_error *grpc_error_set_str(grpc_error *src, grpc_error_strs which, /// Caller does NOT own return value. const char *grpc_error_get_str(grpc_error *error, grpc_error_strs which); -/// A utility function to get the status code and message to be returned -/// to the application. If not set in the top-level message, looks -/// through child errors until it finds the first one with these attributes. -void grpc_error_get_status(grpc_error *error, grpc_status_code *code, - const char **msg); - /// Add a child error: an error that is believed to have contributed to this /// error occurring. Allows root causing high level errors from lower level /// errors that contributed to them. diff --git a/src/core/lib/iomgr/error_internal.h b/src/core/lib/iomgr/error_internal.h new file mode 100644 index 0000000000..1c89ead4ed --- /dev/null +++ b/src/core/lib/iomgr/error_internal.h @@ -0,0 +1,54 @@ +/* + * + * Copyright 2016, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#ifndef GRPC_CORE_LIB_IOMGR_ERROR_INTERNAL_H +#define GRPC_CORE_LIB_IOMGR_ERROR_INTERNAL_H + +#include <inttypes.h> +#include <stdbool.h> + +#include <grpc/support/avl.h> + +struct grpc_error { + gpr_refcount refs; + gpr_avl ints; + gpr_avl strs; + gpr_avl times; + gpr_avl errs; + uintptr_t next_err; + gpr_atm error_string; +}; + +bool grpc_error_is_special(grpc_error *err); + +#endif /* GRPC_CORE_LIB_IOMGR_ERROR_INTERNAL_H */ diff --git a/src/core/lib/iomgr/ev_epoll_linux.c b/src/core/lib/iomgr/ev_epoll_linux.c index d6664aead2..39b5c0032e 100644 --- a/src/core/lib/iomgr/ev_epoll_linux.c +++ b/src/core/lib/iomgr/ev_epoll_linux.c @@ -321,7 +321,7 @@ gpr_atm g_epoll_sync; #endif /* defined(GRPC_TSAN) */ static const grpc_closure_scheduler_vtable workqueue_scheduler_vtable = { - workqueue_enqueue, workqueue_enqueue}; + workqueue_enqueue, workqueue_enqueue, "workqueue"}; static void pi_add_ref(polling_island *pi); static void pi_unref(grpc_exec_ctx *exec_ctx, polling_island *pi); diff --git a/src/core/lib/iomgr/ev_posix.c b/src/core/lib/iomgr/ev_posix.c index 2975d619e1..c106ba5400 100644 --- a/src/core/lib/iomgr/ev_posix.c +++ b/src/core/lib/iomgr/ev_posix.c @@ -52,6 +52,8 @@ * tests */ grpc_poll_function_type grpc_poll_function = poll; +grpc_wakeup_fd grpc_global_wakeup_fd; + static const grpc_event_engine_vtable *g_event_engine; static const char *g_poll_strategy_name = NULL; diff --git a/src/core/lib/iomgr/exec_ctx.c b/src/core/lib/iomgr/exec_ctx.c index 6aa788f8e5..83bb436bd0 100644 --- a/src/core/lib/iomgr/exec_ctx.c +++ b/src/core/lib/iomgr/exec_ctx.c @@ -42,11 +42,16 @@ #include "src/core/lib/profiling/timers.h" bool grpc_exec_ctx_ready_to_finish(grpc_exec_ctx *exec_ctx) { - if (!exec_ctx->cached_ready_to_finish) { - exec_ctx->cached_ready_to_finish = exec_ctx->check_ready_to_finish( - exec_ctx, exec_ctx->check_ready_to_finish_arg); + if ((exec_ctx->flags & GRPC_EXEC_CTX_FLAG_IS_FINISHED) == 0) { + if (exec_ctx->check_ready_to_finish(exec_ctx, + exec_ctx->check_ready_to_finish_arg)) { + exec_ctx->flags |= GRPC_EXEC_CTX_FLAG_IS_FINISHED; + return true; + } + return false; + } else { + return true; } - return exec_ctx->cached_ready_to_finish; } bool grpc_never_ready_to_finish(grpc_exec_ctx *exec_ctx, void *arg_ignored) { @@ -82,7 +87,7 @@ bool grpc_exec_ctx_flush(grpc_exec_ctx *exec_ctx) { } void grpc_exec_ctx_finish(grpc_exec_ctx *exec_ctx) { - exec_ctx->cached_ready_to_finish = true; + exec_ctx->flags |= GRPC_EXEC_CTX_FLAG_IS_FINISHED; grpc_exec_ctx_flush(exec_ctx); } @@ -101,6 +106,6 @@ void grpc_exec_ctx_global_init(void) {} void grpc_exec_ctx_global_shutdown(void) {} static const grpc_closure_scheduler_vtable exec_ctx_scheduler_vtable = { - exec_ctx_run, exec_ctx_sched}; + exec_ctx_run, exec_ctx_sched, "exec_ctx"}; static grpc_closure_scheduler exec_ctx_scheduler = {&exec_ctx_scheduler_vtable}; grpc_closure_scheduler *grpc_schedule_on_exec_ctx = &exec_ctx_scheduler; diff --git a/src/core/lib/iomgr/exec_ctx.h b/src/core/lib/iomgr/exec_ctx.h index e566f1b3e8..f99a0fee5f 100644 --- a/src/core/lib/iomgr/exec_ctx.h +++ b/src/core/lib/iomgr/exec_ctx.h @@ -43,6 +43,13 @@ typedef struct grpc_workqueue grpc_workqueue; typedef struct grpc_combiner grpc_combiner; +/* This exec_ctx is ready to return: either pre-populated, or cached as soon as + the finish_check returns true */ +#define GRPC_EXEC_CTX_FLAG_IS_FINISHED 1 +/* The exec_ctx's thread is (potentially) owned by a call or channel: care + should be given to not delete said call/channel from this exec_ctx */ +#define GRPC_EXEC_CTX_FLAG_THREAD_RESOURCE_LOOP 2 + /** Execution context. * A bag of data that collects information along a callstack. * Generally created at public API entry points, and passed down as @@ -63,36 +70,26 @@ typedef struct grpc_combiner grpc_combiner; * - Instances are always passed as the first argument to a function that * takes it, and always as a pointer (grpc_exec_ctx is never copied). */ -#ifndef GRPC_EXECUTION_CONTEXT_SANITIZER struct grpc_exec_ctx { grpc_closure_list closure_list; /** currently active combiner: updated only via combiner.c */ grpc_combiner *active_combiner; /** last active combiner in the active combiner list */ grpc_combiner *last_combiner; - bool cached_ready_to_finish; + uintptr_t flags; void *check_ready_to_finish_arg; bool (*check_ready_to_finish)(grpc_exec_ctx *exec_ctx, void *arg); }; /* initializer for grpc_exec_ctx: prefer to use GRPC_EXEC_CTX_INIT whenever possible */ -#define GRPC_EXEC_CTX_INIT_WITH_FINISH_CHECK(finish_check, finish_check_arg) \ - { GRPC_CLOSURE_LIST_INIT, NULL, NULL, false, finish_check_arg, finish_check } -#else -struct grpc_exec_ctx { - bool cached_ready_to_finish; - void *check_ready_to_finish_arg; - bool (*check_ready_to_finish)(grpc_exec_ctx *exec_ctx, void *arg); -}; -#define GRPC_EXEC_CTX_INIT_WITH_FINISH_CHECK(finish_check, finish_check_arg) \ - { false, finish_check_arg, finish_check } -#endif +#define GRPC_EXEC_CTX_INITIALIZER(flags, finish_check, finish_check_arg) \ + { GRPC_CLOSURE_LIST_INIT, NULL, NULL, flags, finish_check_arg, finish_check } /* initialize an execution context at the top level of an API call into grpc (this is safe to use elsewhere, though possibly not as efficient) */ #define GRPC_EXEC_CTX_INIT \ - GRPC_EXEC_CTX_INIT_WITH_FINISH_CHECK(grpc_always_ready_to_finish, NULL) + GRPC_EXEC_CTX_INITIALIZER(GRPC_EXEC_CTX_FLAG_IS_FINISHED, NULL, NULL) extern grpc_closure_scheduler *grpc_schedule_on_exec_ctx; diff --git a/src/core/lib/iomgr/executor.c b/src/core/lib/iomgr/executor.c index 852775564f..a5b62aa888 100644 --- a/src/core/lib/iomgr/executor.c +++ b/src/core/lib/iomgr/executor.c @@ -158,7 +158,7 @@ void grpc_executor_shutdown(grpc_exec_ctx *exec_ctx) { gpr_mu_destroy(&g_executor.mu); } -static const grpc_closure_scheduler_vtable executor_vtable = {executor_push, - executor_push}; +static const grpc_closure_scheduler_vtable executor_vtable = { + executor_push, executor_push, "executor"}; static grpc_closure_scheduler executor_scheduler = {&executor_vtable}; grpc_closure_scheduler *grpc_executor_scheduler = &executor_scheduler; diff --git a/src/core/lib/iomgr/load_file.c b/src/core/lib/iomgr/load_file.c index 217bc5da59..f40c8b28cc 100644 --- a/src/core/lib/iomgr/load_file.c +++ b/src/core/lib/iomgr/load_file.c @@ -47,7 +47,7 @@ grpc_error *grpc_load_file(const char *filename, int add_null_terminator, grpc_slice *output) { unsigned char *contents = NULL; size_t contents_size = 0; - grpc_slice result = gpr_empty_slice(); + grpc_slice result = grpc_empty_slice(); FILE *file; size_t bytes_read = 0; grpc_error *error = GRPC_ERROR_NONE; diff --git a/src/core/lib/iomgr/resource_quota.c b/src/core/lib/iomgr/resource_quota.c index 42a044df77..21aa05e57a 100644 --- a/src/core/lib/iomgr/resource_quota.c +++ b/src/core/lib/iomgr/resource_quota.c @@ -378,11 +378,15 @@ static void ru_slice_unref(grpc_exec_ctx *exec_ctx, void *p) { } } +static const grpc_slice_refcount_vtable ru_slice_vtable = { + ru_slice_ref, ru_slice_unref, grpc_slice_default_eq_impl, + grpc_slice_default_hash_impl}; + static grpc_slice ru_slice_create(grpc_resource_user *resource_user, size_t size) { ru_slice_refcount *rc = gpr_malloc(sizeof(ru_slice_refcount) + size); - rc->base.ref = ru_slice_ref; - rc->base.unref = ru_slice_unref; + rc->base.vtable = &ru_slice_vtable; + rc->base.sub_refcount = &rc->base; gpr_ref_init(&rc->refs, 1); rc->resource_user = resource_user; rc->size = size; diff --git a/src/core/lib/iomgr/tcp_client_posix.c b/src/core/lib/iomgr/tcp_client_posix.c index 9a77c92016..16b0f4e73c 100644 --- a/src/core/lib/iomgr/tcp_client_posix.c +++ b/src/core/lib/iomgr/tcp_client_posix.c @@ -118,7 +118,6 @@ static void tc_on_alarm(grpc_exec_ctx *exec_ctx, void *acp, grpc_error *error) { const char *str = grpc_error_string(error); gpr_log(GPR_DEBUG, "CLIENT_CONNECT: %s: on_alarm: error=%s", ac->addr_str, str); - grpc_error_free_string(str); } gpr_mu_lock(&ac->mu); if (ac->fd != NULL) { @@ -178,7 +177,6 @@ static void on_writable(grpc_exec_ctx *exec_ctx, void *acp, grpc_error *error) { const char *str = grpc_error_string(error); gpr_log(GPR_DEBUG, "CLIENT_CONNECT: %s: on_writable: error=%s", ac->addr_str, str); - grpc_error_free_string(str); } gpr_mu_lock(&ac->mu); diff --git a/src/core/lib/iomgr/tcp_posix.c b/src/core/lib/iomgr/tcp_posix.c index ece44978b0..a33e63e845 100644 --- a/src/core/lib/iomgr/tcp_posix.c +++ b/src/core/lib/iomgr/tcp_posix.c @@ -181,7 +181,7 @@ static void call_read_cb(grpc_exec_ctx *exec_ctx, grpc_tcp *tcp, size_t i; const char *str = grpc_error_string(error); gpr_log(GPR_DEBUG, "read: error=%s", str); - grpc_error_free_string(str); + for (i = 0; i < tcp->incoming_buffer->count; i++) { char *dump = grpc_dump_slice(tcp->incoming_buffer->slices[i], GPR_DUMP_HEX | GPR_DUMP_ASCII); @@ -435,7 +435,6 @@ static void tcp_handle_write(grpc_exec_ctx *exec_ctx, void *arg /* grpc_tcp */, if (grpc_tcp_trace) { const char *str = grpc_error_string(error); gpr_log(GPR_DEBUG, "write: %s", str); - grpc_error_free_string(str); } grpc_closure_run(exec_ctx, cb, error); @@ -485,7 +484,6 @@ static void tcp_write(grpc_exec_ctx *exec_ctx, grpc_endpoint *ep, if (grpc_tcp_trace) { const char *str = grpc_error_string(error); gpr_log(GPR_DEBUG, "write: %s", str); - grpc_error_free_string(str); } grpc_closure_sched(exec_ctx, cb, error); } diff --git a/src/core/lib/iomgr/tcp_server_windows.c b/src/core/lib/iomgr/tcp_server_windows.c index dafe851ce8..bd4b9b2df1 100644 --- a/src/core/lib/iomgr/tcp_server_windows.c +++ b/src/core/lib/iomgr/tcp_server_windows.c @@ -343,7 +343,7 @@ static void on_accept(grpc_exec_ctx *exec_ctx, void *arg, grpc_error *error) { if (error != GRPC_ERROR_NONE) { const char *msg = grpc_error_string(error); gpr_log(GPR_INFO, "Skipping on_accept due to error: %s", msg); - grpc_error_free_string(msg); + gpr_mu_unlock(&sp->server->mu); return; } diff --git a/src/core/lib/iomgr/tcp_uv.c b/src/core/lib/iomgr/tcp_uv.c index 3ddc79706b..7f4ea49a1c 100644 --- a/src/core/lib/iomgr/tcp_uv.c +++ b/src/core/lib/iomgr/tcp_uv.c @@ -48,6 +48,7 @@ #include "src/core/lib/iomgr/network_status_tracker.h" #include "src/core/lib/iomgr/resource_quota.h" #include "src/core/lib/iomgr/tcp_uv.h" +#include "src/core/lib/slice/slice_internal.h" #include "src/core/lib/slice/slice_string_helpers.h" #include "src/core/lib/support/string.h" @@ -156,7 +157,7 @@ static void read_callback(uv_stream_t *stream, ssize_t nread, size_t i; const char *str = grpc_error_string(error); gpr_log(GPR_DEBUG, "read: error=%s", str); - grpc_error_free_string(str); + for (i = 0; i < tcp->read_slices->count; i++) { char *dump = grpc_dump_slice(tcp->read_slices->slices[i], GPR_DUMP_HEX | GPR_DUMP_ASCII); |