Nicolas Noble | b7ebd3b | 2014-11-26 16:33:03 -0800 | [diff] [blame] | 1 | /* |
| 2 | * |
Jan Tattermusch | 7897ae9 | 2017-06-07 22:57:36 +0200 | [diff] [blame] | 3 | * Copyright 2015 gRPC authors. |
Nicolas Noble | b7ebd3b | 2014-11-26 16:33:03 -0800 | [diff] [blame] | 4 | * |
Jan Tattermusch | 7897ae9 | 2017-06-07 22:57:36 +0200 | [diff] [blame] | 5 | * Licensed under the Apache License, Version 2.0 (the "License"); |
| 6 | * you may not use this file except in compliance with the License. |
| 7 | * You may obtain a copy of the License at |
Nicolas Noble | b7ebd3b | 2014-11-26 16:33:03 -0800 | [diff] [blame] | 8 | * |
Jan Tattermusch | 7897ae9 | 2017-06-07 22:57:36 +0200 | [diff] [blame] | 9 | * http://www.apache.org/licenses/LICENSE-2.0 |
Nicolas Noble | b7ebd3b | 2014-11-26 16:33:03 -0800 | [diff] [blame] | 10 | * |
Jan Tattermusch | 7897ae9 | 2017-06-07 22:57:36 +0200 | [diff] [blame] | 11 | * Unless required by applicable law or agreed to in writing, software |
| 12 | * distributed under the License is distributed on an "AS IS" BASIS, |
| 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| 14 | * See the License for the specific language governing permissions and |
| 15 | * limitations under the License. |
Nicolas Noble | b7ebd3b | 2014-11-26 16:33:03 -0800 | [diff] [blame] | 16 | * |
| 17 | */ |
| 18 | |
Craig Tiller | 9533d04 | 2016-03-25 17:11:06 -0700 | [diff] [blame] | 19 | #include "src/core/lib/transport/transport.h" |
Craig Tiller | e0221ff | 2016-07-11 15:56:08 -0700 | [diff] [blame] | 20 | |
| 21 | #include <string.h> |
| 22 | |
Craig Tiller | 45ce927 | 2015-07-31 11:22:35 -0700 | [diff] [blame] | 23 | #include <grpc/support/alloc.h> |
Craig Tiller | 9d35a1f | 2015-11-02 14:16:12 -0800 | [diff] [blame] | 24 | #include <grpc/support/atm.h> |
Craig Tiller | 45ce927 | 2015-07-31 11:22:35 -0700 | [diff] [blame] | 25 | #include <grpc/support/log.h> |
Craig Tiller | e2d6a61 | 2016-03-09 10:14:30 -0800 | [diff] [blame] | 26 | #include <grpc/support/sync.h> |
Craig Tiller | e0221ff | 2016-07-11 15:56:08 -0700 | [diff] [blame] | 27 | |
Craig Tiller | 7c70b6c | 2017-01-23 07:48:42 -0800 | [diff] [blame] | 28 | #include "src/core/lib/iomgr/executor.h" |
Craig Tiller | a59c16c | 2016-10-31 07:25:01 -0700 | [diff] [blame] | 29 | #include "src/core/lib/slice/slice_internal.h" |
Craig Tiller | 0f31080 | 2016-10-26 16:25:56 -0700 | [diff] [blame] | 30 | #include "src/core/lib/slice/slice_string_helpers.h" |
Craig Tiller | f0f70a8 | 2016-06-23 13:55:06 -0700 | [diff] [blame] | 31 | #include "src/core/lib/support/string.h" |
Craig Tiller | 9533d04 | 2016-03-25 17:11:06 -0700 | [diff] [blame] | 32 | #include "src/core/lib/transport/transport_impl.h" |
Nicolas Noble | b7ebd3b | 2014-11-26 16:33:03 -0800 | [diff] [blame] | 33 | |
ncteisen | a135485 | 2017-06-08 16:25:53 -0700 | [diff] [blame] | 34 | #ifndef NDEBUG |
ncteisen | 7712c7c | 2017-07-12 23:11:27 -0700 | [diff] [blame] | 35 | grpc_tracer_flag grpc_trace_stream_refcount = |
| 36 | GRPC_TRACER_INITIALIZER(false, "stream_refcount"); |
ncteisen | a135485 | 2017-06-08 16:25:53 -0700 | [diff] [blame] | 37 | #endif |
ncteisen | 9c43fc0 | 2017-06-08 16:06:23 -0700 | [diff] [blame] | 38 | |
| 39 | #ifndef NDEBUG |
Craig Tiller | 9d35a1f | 2015-11-02 14:16:12 -0800 | [diff] [blame] | 40 | void grpc_stream_ref(grpc_stream_refcount *refcount, const char *reason) { |
ncteisen | 9c43fc0 | 2017-06-08 16:06:23 -0700 | [diff] [blame] | 41 | if (GRPC_TRACER_ON(grpc_trace_stream_refcount)) { |
| 42 | gpr_atm val = gpr_atm_no_barrier_load(&refcount->refs.count); |
| 43 | gpr_log(GPR_DEBUG, "%s %p:%p REF %" PRIdPTR "->%" PRIdPTR " %s", |
| 44 | refcount->object_type, refcount, refcount->destroy.cb_arg, val, |
| 45 | val + 1, reason); |
| 46 | } |
Craig Tiller | 9d35a1f | 2015-11-02 14:16:12 -0800 | [diff] [blame] | 47 | #else |
| 48 | void grpc_stream_ref(grpc_stream_refcount *refcount) { |
| 49 | #endif |
Craig Tiller | 0cb803d | 2016-03-02 22:17:24 -0800 | [diff] [blame] | 50 | gpr_ref_non_zero(&refcount->refs); |
Craig Tiller | 9d35a1f | 2015-11-02 14:16:12 -0800 | [diff] [blame] | 51 | } |
| 52 | |
ncteisen | 9c43fc0 | 2017-06-08 16:06:23 -0700 | [diff] [blame] | 53 | #ifndef NDEBUG |
Craig Tiller | 9d35a1f | 2015-11-02 14:16:12 -0800 | [diff] [blame] | 54 | void grpc_stream_unref(grpc_exec_ctx *exec_ctx, grpc_stream_refcount *refcount, |
| 55 | const char *reason) { |
ncteisen | 9c43fc0 | 2017-06-08 16:06:23 -0700 | [diff] [blame] | 56 | if (GRPC_TRACER_ON(grpc_trace_stream_refcount)) { |
| 57 | gpr_atm val = gpr_atm_no_barrier_load(&refcount->refs.count); |
| 58 | gpr_log(GPR_DEBUG, "%s %p:%p UNREF %" PRIdPTR "->%" PRIdPTR " %s", |
| 59 | refcount->object_type, refcount, refcount->destroy.cb_arg, val, |
| 60 | val - 1, reason); |
| 61 | } |
Craig Tiller | 9d35a1f | 2015-11-02 14:16:12 -0800 | [diff] [blame] | 62 | #else |
| 63 | void grpc_stream_unref(grpc_exec_ctx *exec_ctx, |
| 64 | grpc_stream_refcount *refcount) { |
| 65 | #endif |
| 66 | if (gpr_unref(&refcount->refs)) { |
Craig Tiller | 7c70b6c | 2017-01-23 07:48:42 -0800 | [diff] [blame] | 67 | if (exec_ctx->flags & GRPC_EXEC_CTX_FLAG_THREAD_RESOURCE_LOOP) { |
| 68 | /* Ick. |
| 69 | The thread we're running on MAY be owned (indirectly) by a call-stack. |
| 70 | If that's the case, destroying the call-stack MAY try to destroy the |
| 71 | thread, which is a tangled mess that we just don't want to ever have to |
| 72 | cope with. |
| 73 | Throw this over to the executor (on a core-owned thread) and process it |
| 74 | there. */ |
Craig Tiller | 7a82afd | 2017-07-18 09:40:40 -0700 | [diff] [blame] | 75 | refcount->destroy.scheduler = |
| 76 | grpc_executor_scheduler(GRPC_EXECUTOR_SHORT); |
Craig Tiller | 7c70b6c | 2017-01-23 07:48:42 -0800 | [diff] [blame] | 77 | } |
ncteisen | 969b46e | 2017-06-08 14:57:11 -0700 | [diff] [blame] | 78 | GRPC_CLOSURE_SCHED(exec_ctx, &refcount->destroy, GRPC_ERROR_NONE); |
Craig Tiller | 9d35a1f | 2015-11-02 14:16:12 -0800 | [diff] [blame] | 79 | } |
| 80 | } |
| 81 | |
Craig Tiller | 295df6d | 2017-03-01 11:28:24 -0800 | [diff] [blame] | 82 | #define STREAM_REF_FROM_SLICE_REF(p) \ |
| 83 | ((grpc_stream_refcount *)(((uint8_t *)p) - \ |
| 84 | offsetof(grpc_stream_refcount, slice_refcount))) |
| 85 | |
| 86 | static void slice_stream_ref(void *p) { |
ncteisen | 9c43fc0 | 2017-06-08 16:06:23 -0700 | [diff] [blame] | 87 | #ifndef NDEBUG |
Craig Tiller | 295df6d | 2017-03-01 11:28:24 -0800 | [diff] [blame] | 88 | grpc_stream_ref(STREAM_REF_FROM_SLICE_REF(p), "slice"); |
| 89 | #else |
| 90 | grpc_stream_ref(STREAM_REF_FROM_SLICE_REF(p)); |
| 91 | #endif |
| 92 | } |
| 93 | |
| 94 | static void slice_stream_unref(grpc_exec_ctx *exec_ctx, void *p) { |
ncteisen | 9c43fc0 | 2017-06-08 16:06:23 -0700 | [diff] [blame] | 95 | #ifndef NDEBUG |
Craig Tiller | 295df6d | 2017-03-01 11:28:24 -0800 | [diff] [blame] | 96 | grpc_stream_unref(exec_ctx, STREAM_REF_FROM_SLICE_REF(p), "slice"); |
| 97 | #else |
| 98 | grpc_stream_unref(exec_ctx, STREAM_REF_FROM_SLICE_REF(p)); |
| 99 | #endif |
| 100 | } |
| 101 | |
| 102 | grpc_slice grpc_slice_from_stream_owned_buffer(grpc_stream_refcount *refcount, |
| 103 | void *buffer, size_t length) { |
| 104 | slice_stream_ref(&refcount->slice_refcount); |
Yash Tibrewal | 533d118 | 2017-09-18 10:48:22 -0700 | [diff] [blame^] | 105 | grpc_slice res; |
| 106 | res.refcount = &refcount->slice_refcount, |
| 107 | res.data.refcounted.bytes = (uint8_t *)buffer; |
| 108 | res.data.refcounted.length = length; |
| 109 | return res; |
Craig Tiller | 295df6d | 2017-03-01 11:28:24 -0800 | [diff] [blame] | 110 | } |
| 111 | |
| 112 | static const grpc_slice_refcount_vtable stream_ref_slice_vtable = { |
| 113 | .ref = slice_stream_ref, |
| 114 | .unref = slice_stream_unref, |
| 115 | .eq = grpc_slice_default_eq_impl, |
| 116 | .hash = grpc_slice_default_hash_impl}; |
| 117 | |
ncteisen | 9c43fc0 | 2017-06-08 16:06:23 -0700 | [diff] [blame] | 118 | #ifndef NDEBUG |
Craig Tiller | 27e5aa4 | 2015-11-24 16:28:54 -0800 | [diff] [blame] | 119 | void grpc_stream_ref_init(grpc_stream_refcount *refcount, int initial_refs, |
| 120 | grpc_iomgr_cb_func cb, void *cb_arg, |
| 121 | const char *object_type) { |
| 122 | refcount->object_type = object_type; |
| 123 | #else |
| 124 | void grpc_stream_ref_init(grpc_stream_refcount *refcount, int initial_refs, |
| 125 | grpc_iomgr_cb_func cb, void *cb_arg) { |
| 126 | #endif |
| 127 | gpr_ref_init(&refcount->refs, initial_refs); |
ncteisen | 969b46e | 2017-06-08 14:57:11 -0700 | [diff] [blame] | 128 | GRPC_CLOSURE_INIT(&refcount->destroy, cb, cb_arg, grpc_schedule_on_exec_ctx); |
Craig Tiller | 295df6d | 2017-03-01 11:28:24 -0800 | [diff] [blame] | 129 | refcount->slice_refcount.vtable = &stream_ref_slice_vtable; |
| 130 | refcount->slice_refcount.sub_refcount = &refcount->slice_refcount; |
Craig Tiller | 27e5aa4 | 2015-11-24 16:28:54 -0800 | [diff] [blame] | 131 | } |
| 132 | |
Craig Tiller | 466129e | 2016-03-09 14:43:18 -0800 | [diff] [blame] | 133 | static void move64(uint64_t *from, uint64_t *to) { |
| 134 | *to += *from; |
| 135 | *from = 0; |
Craig Tiller | e2d6a61 | 2016-03-09 10:14:30 -0800 | [diff] [blame] | 136 | } |
| 137 | |
Craig Tiller | 466129e | 2016-03-09 14:43:18 -0800 | [diff] [blame] | 138 | void grpc_transport_move_one_way_stats(grpc_transport_one_way_stats *from, |
| 139 | grpc_transport_one_way_stats *to) { |
| 140 | move64(&from->framing_bytes, &to->framing_bytes); |
| 141 | move64(&from->data_bytes, &to->data_bytes); |
| 142 | move64(&from->header_bytes, &to->header_bytes); |
| 143 | } |
| 144 | |
| 145 | void grpc_transport_move_stats(grpc_transport_stream_stats *from, |
| 146 | grpc_transport_stream_stats *to) { |
| 147 | grpc_transport_move_one_way_stats(&from->incoming, &to->incoming); |
| 148 | grpc_transport_move_one_way_stats(&from->outgoing, &to->outgoing); |
Craig Tiller | e2d6a61 | 2016-03-09 10:14:30 -0800 | [diff] [blame] | 149 | } |
| 150 | |
Craig Tiller | a82950e | 2015-09-22 12:33:20 -0700 | [diff] [blame] | 151 | size_t grpc_transport_stream_size(grpc_transport *transport) { |
Nicolas Noble | b7ebd3b | 2014-11-26 16:33:03 -0800 | [diff] [blame] | 152 | return transport->vtable->sizeof_stream; |
| 153 | } |
| 154 | |
Craig Tiller | a82950e | 2015-09-22 12:33:20 -0700 | [diff] [blame] | 155 | void grpc_transport_destroy(grpc_exec_ctx *exec_ctx, |
| 156 | grpc_transport *transport) { |
| 157 | transport->vtable->destroy(exec_ctx, transport); |
Nicolas Noble | b7ebd3b | 2014-11-26 16:33:03 -0800 | [diff] [blame] | 158 | } |
| 159 | |
Craig Tiller | a82950e | 2015-09-22 12:33:20 -0700 | [diff] [blame] | 160 | int grpc_transport_init_stream(grpc_exec_ctx *exec_ctx, |
| 161 | grpc_transport *transport, grpc_stream *stream, |
Craig Tiller | 9d35a1f | 2015-11-02 14:16:12 -0800 | [diff] [blame] | 162 | grpc_stream_refcount *refcount, |
Craig Tiller | 7d2c398 | 2017-03-13 12:58:29 -0700 | [diff] [blame] | 163 | const void *server_data, gpr_arena *arena) { |
Craig Tiller | 9d35a1f | 2015-11-02 14:16:12 -0800 | [diff] [blame] | 164 | return transport->vtable->init_stream(exec_ctx, transport, stream, refcount, |
Craig Tiller | 7d2c398 | 2017-03-13 12:58:29 -0700 | [diff] [blame] | 165 | server_data, arena); |
Nicolas Noble | b7ebd3b | 2014-11-26 16:33:03 -0800 | [diff] [blame] | 166 | } |
| 167 | |
Craig Tiller | a82950e | 2015-09-22 12:33:20 -0700 | [diff] [blame] | 168 | void grpc_transport_perform_stream_op(grpc_exec_ctx *exec_ctx, |
| 169 | grpc_transport *transport, |
| 170 | grpc_stream *stream, |
Craig Tiller | a0f3abd | 2017-03-31 15:42:16 -0700 | [diff] [blame] | 171 | grpc_transport_stream_op_batch *op) { |
Craig Tiller | a82950e | 2015-09-22 12:33:20 -0700 | [diff] [blame] | 172 | transport->vtable->perform_stream_op(exec_ctx, transport, stream, op); |
Craig Tiller | 3f47542 | 2015-06-25 10:43:05 -0700 | [diff] [blame] | 173 | } |
| 174 | |
Craig Tiller | a82950e | 2015-09-22 12:33:20 -0700 | [diff] [blame] | 175 | void grpc_transport_perform_op(grpc_exec_ctx *exec_ctx, |
| 176 | grpc_transport *transport, |
| 177 | grpc_transport_op *op) { |
| 178 | transport->vtable->perform_op(exec_ctx, transport, op); |
Nicolas Noble | b7ebd3b | 2014-11-26 16:33:03 -0800 | [diff] [blame] | 179 | } |
| 180 | |
David Garcia Quintas | f72eb97 | 2016-05-03 18:28:09 -0700 | [diff] [blame] | 181 | void grpc_transport_set_pops(grpc_exec_ctx *exec_ctx, grpc_transport *transport, |
David Garcia Quintas | 2a50dfe | 2016-05-31 15:09:12 -0700 | [diff] [blame] | 182 | grpc_stream *stream, |
| 183 | grpc_polling_entity *pollent) { |
David Garcia Quintas | f72eb97 | 2016-05-03 18:28:09 -0700 | [diff] [blame] | 184 | grpc_pollset *pollset; |
| 185 | grpc_pollset_set *pollset_set; |
David Garcia Quintas | c4d5112 | 2016-06-06 14:56:02 -0700 | [diff] [blame] | 186 | if ((pollset = grpc_polling_entity_pollset(pollent)) != NULL) { |
David Garcia Quintas | f72eb97 | 2016-05-03 18:28:09 -0700 | [diff] [blame] | 187 | transport->vtable->set_pollset(exec_ctx, transport, stream, pollset); |
David Garcia Quintas | c4d5112 | 2016-06-06 14:56:02 -0700 | [diff] [blame] | 188 | } else if ((pollset_set = grpc_polling_entity_pollset_set(pollent)) != NULL) { |
David Garcia Quintas | f72eb97 | 2016-05-03 18:28:09 -0700 | [diff] [blame] | 189 | transport->vtable->set_pollset_set(exec_ctx, transport, stream, |
| 190 | pollset_set); |
| 191 | } else { |
| 192 | abort(); |
| 193 | } |
Craig Tiller | 9d35a1f | 2015-11-02 14:16:12 -0800 | [diff] [blame] | 194 | } |
| 195 | |
Craig Tiller | a82950e | 2015-09-22 12:33:20 -0700 | [diff] [blame] | 196 | void grpc_transport_destroy_stream(grpc_exec_ctx *exec_ctx, |
| 197 | grpc_transport *transport, |
Craig Tiller | d426cac | 2017-03-13 12:30:45 -0700 | [diff] [blame] | 198 | grpc_stream *stream, |
| 199 | grpc_closure *then_schedule_closure) { |
Craig Tiller | 2c8063c | 2016-03-22 22:12:15 -0700 | [diff] [blame] | 200 | transport->vtable->destroy_stream(exec_ctx, transport, stream, |
Craig Tiller | d426cac | 2017-03-13 12:30:45 -0700 | [diff] [blame] | 201 | then_schedule_closure); |
Nicolas Noble | b7ebd3b | 2014-11-26 16:33:03 -0800 | [diff] [blame] | 202 | } |
| 203 | |
Yuchen Zeng | 5ab4ca5 | 2016-10-24 10:49:55 -0700 | [diff] [blame] | 204 | grpc_endpoint *grpc_transport_get_endpoint(grpc_exec_ctx *exec_ctx, |
| 205 | grpc_transport *transport) { |
| 206 | return transport->vtable->get_endpoint(exec_ctx, transport); |
| 207 | } |
| 208 | |
Mark D. Roth | 5794061 | 2017-07-26 14:29:52 -0700 | [diff] [blame] | 209 | // This comment should be sung to the tune of |
| 210 | // "Supercalifragilisticexpialidocious": |
| 211 | // |
Vijay Pai | ff17b05 | 2017-06-27 11:05:29 -0700 | [diff] [blame] | 212 | // grpc_transport_stream_op_batch_finish_with_failure |
| 213 | // is a function that must always unref cancel_error |
| 214 | // though it lives in lib, it handles transport stream ops sure |
| 215 | // it's grpc_transport_stream_op_batch_finish_with_failure |
Craig Tiller | e1b51da | 2017-03-31 15:44:33 -0700 | [diff] [blame] | 216 | void grpc_transport_stream_op_batch_finish_with_failure( |
Mark D. Roth | 5794061 | 2017-07-26 14:29:52 -0700 | [diff] [blame] | 217 | grpc_exec_ctx *exec_ctx, grpc_transport_stream_op_batch *batch, |
Mark D. Roth | 764cf04 | 2017-09-01 09:00:06 -0700 | [diff] [blame] | 218 | grpc_error *error, grpc_call_combiner *call_combiner) { |
Mark D. Roth | 5794061 | 2017-07-26 14:29:52 -0700 | [diff] [blame] | 219 | if (batch->send_message) { |
| 220 | grpc_byte_stream_destroy(exec_ctx, |
| 221 | batch->payload->send_message.send_message); |
| 222 | } |
| 223 | if (batch->recv_message) { |
Mark D. Roth | 764cf04 | 2017-09-01 09:00:06 -0700 | [diff] [blame] | 224 | GRPC_CALL_COMBINER_START(exec_ctx, call_combiner, |
| 225 | batch->payload->recv_message.recv_message_ready, |
| 226 | GRPC_ERROR_REF(error), |
| 227 | "failing recv_message_ready"); |
Craig Tiller | ea54b8c | 2017-03-01 16:58:28 -0800 | [diff] [blame] | 228 | } |
Mark D. Roth | 5794061 | 2017-07-26 14:29:52 -0700 | [diff] [blame] | 229 | if (batch->recv_initial_metadata) { |
Mark D. Roth | 764cf04 | 2017-09-01 09:00:06 -0700 | [diff] [blame] | 230 | GRPC_CALL_COMBINER_START( |
| 231 | exec_ctx, call_combiner, |
Mark D. Roth | 5794061 | 2017-07-26 14:29:52 -0700 | [diff] [blame] | 232 | batch->payload->recv_initial_metadata.recv_initial_metadata_ready, |
Mark D. Roth | 764cf04 | 2017-09-01 09:00:06 -0700 | [diff] [blame] | 233 | GRPC_ERROR_REF(error), "failing recv_initial_metadata_ready"); |
Craig Tiller | ea54b8c | 2017-03-01 16:58:28 -0800 | [diff] [blame] | 234 | } |
Mark D. Roth | 5794061 | 2017-07-26 14:29:52 -0700 | [diff] [blame] | 235 | GRPC_CLOSURE_SCHED(exec_ctx, batch->on_complete, error); |
| 236 | if (batch->cancel_stream) { |
| 237 | GRPC_ERROR_UNREF(batch->payload->cancel_stream.cancel_error); |
Craig Tiller | ea54b8c | 2017-03-01 16:58:28 -0800 | [diff] [blame] | 238 | } |
Craig Tiller | 7e320ba | 2015-04-23 16:28:07 -0700 | [diff] [blame] | 239 | } |
Craig Tiller | 2ea37fd | 2015-04-24 13:03:49 -0700 | [diff] [blame] | 240 | |
Craig Tiller | a82950e | 2015-09-22 12:33:20 -0700 | [diff] [blame] | 241 | typedef struct { |
Craig Tiller | e0221ff | 2016-07-11 15:56:08 -0700 | [diff] [blame] | 242 | grpc_closure outer_on_complete; |
| 243 | grpc_closure *inner_on_complete; |
| 244 | grpc_transport_op op; |
| 245 | } made_transport_op; |
| 246 | |
| 247 | static void destroy_made_transport_op(grpc_exec_ctx *exec_ctx, void *arg, |
| 248 | grpc_error *error) { |
Yash Tibrewal | ca3c1c0 | 2017-09-07 22:47:16 -0700 | [diff] [blame] | 249 | made_transport_op *op = (made_transport_op *)arg; |
ncteisen | 969b46e | 2017-06-08 14:57:11 -0700 | [diff] [blame] | 250 | GRPC_CLOSURE_SCHED(exec_ctx, op->inner_on_complete, GRPC_ERROR_REF(error)); |
Craig Tiller | e0221ff | 2016-07-11 15:56:08 -0700 | [diff] [blame] | 251 | gpr_free(op); |
| 252 | } |
| 253 | |
| 254 | grpc_transport_op *grpc_make_transport_op(grpc_closure *on_complete) { |
Yash Tibrewal | ca3c1c0 | 2017-09-07 22:47:16 -0700 | [diff] [blame] | 255 | made_transport_op *op = (made_transport_op *)gpr_malloc(sizeof(*op)); |
ncteisen | 969b46e | 2017-06-08 14:57:11 -0700 | [diff] [blame] | 256 | GRPC_CLOSURE_INIT(&op->outer_on_complete, destroy_made_transport_op, op, |
Craig Tiller | 91031da | 2016-12-28 15:44:25 -0800 | [diff] [blame] | 257 | grpc_schedule_on_exec_ctx); |
Craig Tiller | e0221ff | 2016-07-11 15:56:08 -0700 | [diff] [blame] | 258 | op->inner_on_complete = on_complete; |
| 259 | memset(&op->op, 0, sizeof(op->op)); |
Craig Tiller | ed334f0 | 2016-07-12 09:15:07 -0700 | [diff] [blame] | 260 | op->op.on_consumed = &op->outer_on_complete; |
Craig Tiller | e0221ff | 2016-07-11 15:56:08 -0700 | [diff] [blame] | 261 | return &op->op; |
| 262 | } |
Craig Tiller | dfd3a8f | 2016-08-24 09:43:45 -0700 | [diff] [blame] | 263 | |
| 264 | typedef struct { |
| 265 | grpc_closure outer_on_complete; |
| 266 | grpc_closure *inner_on_complete; |
Craig Tiller | a0f3abd | 2017-03-31 15:42:16 -0700 | [diff] [blame] | 267 | grpc_transport_stream_op_batch op; |
| 268 | grpc_transport_stream_op_batch_payload payload; |
Craig Tiller | dfd3a8f | 2016-08-24 09:43:45 -0700 | [diff] [blame] | 269 | } made_transport_stream_op; |
| 270 | |
| 271 | static void destroy_made_transport_stream_op(grpc_exec_ctx *exec_ctx, void *arg, |
| 272 | grpc_error *error) { |
Yash Tibrewal | ca3c1c0 | 2017-09-07 22:47:16 -0700 | [diff] [blame] | 273 | made_transport_stream_op *op = (made_transport_stream_op *)arg; |
Craig Tiller | c5b90df | 2017-03-10 16:11:08 -0800 | [diff] [blame] | 274 | grpc_closure *c = op->inner_on_complete; |
Craig Tiller | dfd3a8f | 2016-08-24 09:43:45 -0700 | [diff] [blame] | 275 | gpr_free(op); |
ncteisen | 969b46e | 2017-06-08 14:57:11 -0700 | [diff] [blame] | 276 | GRPC_CLOSURE_RUN(exec_ctx, c, GRPC_ERROR_REF(error)); |
Craig Tiller | dfd3a8f | 2016-08-24 09:43:45 -0700 | [diff] [blame] | 277 | } |
| 278 | |
Craig Tiller | a0f3abd | 2017-03-31 15:42:16 -0700 | [diff] [blame] | 279 | grpc_transport_stream_op_batch *grpc_make_transport_stream_op( |
Craig Tiller | dfd3a8f | 2016-08-24 09:43:45 -0700 | [diff] [blame] | 280 | grpc_closure *on_complete) { |
Yash Tibrewal | ca3c1c0 | 2017-09-07 22:47:16 -0700 | [diff] [blame] | 281 | made_transport_stream_op *op = |
| 282 | (made_transport_stream_op *)gpr_zalloc(sizeof(*op)); |
Craig Tiller | ea54b8c | 2017-03-01 16:58:28 -0800 | [diff] [blame] | 283 | op->op.payload = &op->payload; |
ncteisen | 969b46e | 2017-06-08 14:57:11 -0700 | [diff] [blame] | 284 | GRPC_CLOSURE_INIT(&op->outer_on_complete, destroy_made_transport_stream_op, |
Craig Tiller | 91031da | 2016-12-28 15:44:25 -0800 | [diff] [blame] | 285 | op, grpc_schedule_on_exec_ctx); |
Craig Tiller | dfd3a8f | 2016-08-24 09:43:45 -0700 | [diff] [blame] | 286 | op->inner_on_complete = on_complete; |
Craig Tiller | dfd3a8f | 2016-08-24 09:43:45 -0700 | [diff] [blame] | 287 | op->op.on_complete = &op->outer_on_complete; |
| 288 | return &op->op; |
| 289 | } |