diff options
author | Mark D. Roth <roth@google.com> | 2017-03-15 08:06:21 -0700 |
---|---|---|
committer | Mark D. Roth <roth@google.com> | 2017-03-15 08:06:21 -0700 |
commit | 3a91707acefc5e099f37ee24c19abfd16fabef8b (patch) | |
tree | a4a7837b399ca19105a0e807ea93a12d7814bc8e /src/core/lib/transport | |
parent | 02612c163e949ed70a399cf9dd311457bb29c902 (diff) | |
parent | 3cafec2f55f66e3df61569579c8259b2e5b5ee00 (diff) |
Merge remote-tracking branch 'upstream/master' into retry_throttle
Diffstat (limited to 'src/core/lib/transport')
-rw-r--r-- | src/core/lib/transport/error_utils.c | 22 | ||||
-rw-r--r-- | src/core/lib/transport/transport.c | 35 | ||||
-rw-r--r-- | src/core/lib/transport/transport.h | 6 |
3 files changed, 52 insertions, 11 deletions
diff --git a/src/core/lib/transport/error_utils.c b/src/core/lib/transport/error_utils.c index da77828d9c..ef55e561fb 100644 --- a/src/core/lib/transport/error_utils.c +++ b/src/core/lib/transport/error_utils.c @@ -44,12 +44,12 @@ static grpc_error *recursively_find_error_with_field(grpc_error *error, } if (grpc_error_is_special(error)) return NULL; // 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_field(child_error, which); - if (result != NULL) return result; + uint8_t slot = error->first_err; + while (slot != UINT8_MAX) { + grpc_linked_error *lerr = (grpc_linked_error *)(error->arena + slot); + grpc_error *result = recursively_find_error_with_field(lerr->err, which); + if (result) return result; + slot = lerr->next; } return NULL; } @@ -112,13 +112,13 @@ bool grpc_error_has_clear_grpc_status(grpc_error *error) { if (grpc_error_get_int(error, GRPC_ERROR_INT_GRPC_STATUS, NULL)) { return true; } - intptr_t key = 0; - while (true) { - grpc_error *child_error = gpr_avl_get(error->errs, (void *)key++); - if (child_error == NULL) break; - if (grpc_error_has_clear_grpc_status(child_error)) { + uint8_t slot = error->first_err; + while (slot != UINT8_MAX) { + grpc_linked_error *lerr = (grpc_linked_error *)(error->arena + slot); + if (grpc_error_has_clear_grpc_status(lerr->err)) { return true; } + slot = lerr->next; } return false; } diff --git a/src/core/lib/transport/transport.c b/src/core/lib/transport/transport.c index 004e748f25..165950e288 100644 --- a/src/core/lib/transport/transport.c +++ b/src/core/lib/transport/transport.c @@ -84,6 +84,39 @@ void grpc_stream_unref(grpc_exec_ctx *exec_ctx, } } +#define STREAM_REF_FROM_SLICE_REF(p) \ + ((grpc_stream_refcount *)(((uint8_t *)p) - \ + offsetof(grpc_stream_refcount, slice_refcount))) + +static void slice_stream_ref(void *p) { +#ifdef GRPC_STREAM_REFCOUNT_DEBUG + grpc_stream_ref(STREAM_REF_FROM_SLICE_REF(p), "slice"); +#else + grpc_stream_ref(STREAM_REF_FROM_SLICE_REF(p)); +#endif +} + +static void slice_stream_unref(grpc_exec_ctx *exec_ctx, void *p) { +#ifdef GRPC_STREAM_REFCOUNT_DEBUG + grpc_stream_unref(exec_ctx, STREAM_REF_FROM_SLICE_REF(p), "slice"); +#else + grpc_stream_unref(exec_ctx, STREAM_REF_FROM_SLICE_REF(p)); +#endif +} + +grpc_slice grpc_slice_from_stream_owned_buffer(grpc_stream_refcount *refcount, + void *buffer, size_t length) { + slice_stream_ref(&refcount->slice_refcount); + return (grpc_slice){.refcount = &refcount->slice_refcount, + .data.refcounted = {.bytes = buffer, .length = length}}; +} + +static const grpc_slice_refcount_vtable stream_ref_slice_vtable = { + .ref = slice_stream_ref, + .unref = slice_stream_unref, + .eq = grpc_slice_default_eq_impl, + .hash = grpc_slice_default_hash_impl}; + #ifdef GRPC_STREAM_REFCOUNT_DEBUG void grpc_stream_ref_init(grpc_stream_refcount *refcount, int initial_refs, grpc_iomgr_cb_func cb, void *cb_arg, @@ -95,6 +128,8 @@ void grpc_stream_ref_init(grpc_stream_refcount *refcount, int initial_refs, #endif gpr_ref_init(&refcount->refs, initial_refs); grpc_closure_init(&refcount->destroy, cb, cb_arg, grpc_schedule_on_exec_ctx); + refcount->slice_refcount.vtable = &stream_ref_slice_vtable; + refcount->slice_refcount.sub_refcount = &refcount->slice_refcount; } static void move64(uint64_t *from, uint64_t *to) { diff --git a/src/core/lib/transport/transport.h b/src/core/lib/transport/transport.h index bb23c0225a..cc1c277b35 100644 --- a/src/core/lib/transport/transport.h +++ b/src/core/lib/transport/transport.h @@ -64,6 +64,7 @@ typedef struct grpc_stream_refcount { #ifdef GRPC_STREAM_REFCOUNT_DEBUG const char *object_type; #endif + grpc_slice_refcount slice_refcount; } grpc_stream_refcount; #ifdef GRPC_STREAM_REFCOUNT_DEBUG @@ -84,6 +85,11 @@ void grpc_stream_unref(grpc_exec_ctx *exec_ctx, grpc_stream_refcount *refcount); grpc_stream_ref_init(rc, ir, cb, cb_arg) #endif +/* Wrap a buffer that is owned by some stream object into a slice that shares + the same refcount */ +grpc_slice grpc_slice_from_stream_owned_buffer(grpc_stream_refcount *refcount, + void *buffer, size_t length); + typedef struct { uint64_t framing_bytes; uint64_t data_bytes; |