blob: 3b555fa9338c3eb9c7f453f14efe45fe6212db5d [file] [log] [blame]
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -08001/*
2 *
Craig Tillera93a25f2016-01-28 13:55:49 -08003 * Copyright 2015-2016, Google Inc.
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -08004 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions are
8 * met:
9 *
10 * * Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * * Redistributions in binary form must reproduce the above
13 * copyright notice, this list of conditions and the following disclaimer
14 * in the documentation and/or other materials provided with the
15 * distribution.
16 * * Neither the name of Google Inc. nor the names of its
17 * contributors may be used to endorse or promote products derived from
18 * this software without specific prior written permission.
19 *
20 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
23 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
24 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
25 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
26 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 *
32 */
33
34#include "src/core/transport/transport.h"
Craig Tiller45ce9272015-07-31 11:22:35 -070035#include <grpc/support/alloc.h>
Craig Tiller9d35a1f2015-11-02 14:16:12 -080036#include <grpc/support/atm.h>
Craig Tiller45ce9272015-07-31 11:22:35 -070037#include <grpc/support/log.h>
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -080038#include "src/core/transport/transport_impl.h"
39
Craig Tiller9d35a1f2015-11-02 14:16:12 -080040#ifdef GRPC_STREAM_REFCOUNT_DEBUG
41void grpc_stream_ref(grpc_stream_refcount *refcount, const char *reason) {
42 gpr_atm val = gpr_atm_no_barrier_load(&refcount->refs.count);
Craig Tiller27e5aa42015-11-24 16:28:54 -080043 gpr_log(GPR_DEBUG, "%s %p:%p REF %d->%d %s", refcount->object_type,
44 refcount, refcount->destroy.cb_arg, val, val + 1, reason);
Craig Tiller9d35a1f2015-11-02 14:16:12 -080045#else
46void grpc_stream_ref(grpc_stream_refcount *refcount) {
47#endif
Craig Tiller0cb803d2016-03-02 22:17:24 -080048 gpr_ref_non_zero(&refcount->refs);
Craig Tiller9d35a1f2015-11-02 14:16:12 -080049}
50
51#ifdef GRPC_STREAM_REFCOUNT_DEBUG
52void grpc_stream_unref(grpc_exec_ctx *exec_ctx, grpc_stream_refcount *refcount,
53 const char *reason) {
54 gpr_atm val = gpr_atm_no_barrier_load(&refcount->refs.count);
Craig Tiller27e5aa42015-11-24 16:28:54 -080055 gpr_log(GPR_DEBUG, "%s %p:%p UNREF %d->%d %s", refcount->object_type,
56 refcount, refcount->destroy.cb_arg, val, val - 1, reason);
Craig Tiller9d35a1f2015-11-02 14:16:12 -080057#else
58void grpc_stream_unref(grpc_exec_ctx *exec_ctx,
59 grpc_stream_refcount *refcount) {
60#endif
61 if (gpr_unref(&refcount->refs)) {
Craig Tiller6c396862016-01-28 13:53:40 -080062 grpc_exec_ctx_enqueue(exec_ctx, &refcount->destroy, true, NULL);
Craig Tiller9d35a1f2015-11-02 14:16:12 -080063 }
64}
65
Craig Tiller27e5aa42015-11-24 16:28:54 -080066#ifdef GRPC_STREAM_REFCOUNT_DEBUG
67void grpc_stream_ref_init(grpc_stream_refcount *refcount, int initial_refs,
68 grpc_iomgr_cb_func cb, void *cb_arg,
69 const char *object_type) {
70 refcount->object_type = object_type;
71#else
72void grpc_stream_ref_init(grpc_stream_refcount *refcount, int initial_refs,
73 grpc_iomgr_cb_func cb, void *cb_arg) {
74#endif
75 gpr_ref_init(&refcount->refs, initial_refs);
76 grpc_closure_init(&refcount->destroy, cb, cb_arg);
77}
78
Craig Tillera82950e2015-09-22 12:33:20 -070079size_t grpc_transport_stream_size(grpc_transport *transport) {
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -080080 return transport->vtable->sizeof_stream;
81}
82
Craig Tillera82950e2015-09-22 12:33:20 -070083void grpc_transport_destroy(grpc_exec_ctx *exec_ctx,
84 grpc_transport *transport) {
85 transport->vtable->destroy(exec_ctx, transport);
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -080086}
87
Craig Tillera82950e2015-09-22 12:33:20 -070088int grpc_transport_init_stream(grpc_exec_ctx *exec_ctx,
89 grpc_transport *transport, grpc_stream *stream,
Craig Tiller9d35a1f2015-11-02 14:16:12 -080090 grpc_stream_refcount *refcount,
91 const void *server_data) {
92 return transport->vtable->init_stream(exec_ctx, transport, stream, refcount,
93 server_data);
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -080094}
95
Craig Tillera82950e2015-09-22 12:33:20 -070096void grpc_transport_perform_stream_op(grpc_exec_ctx *exec_ctx,
97 grpc_transport *transport,
98 grpc_stream *stream,
99 grpc_transport_stream_op *op) {
100 transport->vtable->perform_stream_op(exec_ctx, transport, stream, op);
Craig Tiller3f475422015-06-25 10:43:05 -0700101}
102
Craig Tillera82950e2015-09-22 12:33:20 -0700103void grpc_transport_perform_op(grpc_exec_ctx *exec_ctx,
104 grpc_transport *transport,
105 grpc_transport_op *op) {
106 transport->vtable->perform_op(exec_ctx, transport, op);
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800107}
108
Craig Tiller9d35a1f2015-11-02 14:16:12 -0800109void grpc_transport_set_pollset(grpc_exec_ctx *exec_ctx,
110 grpc_transport *transport, grpc_stream *stream,
111 grpc_pollset *pollset) {
112 transport->vtable->set_pollset(exec_ctx, transport, stream, pollset);
113}
114
Craig Tillera82950e2015-09-22 12:33:20 -0700115void grpc_transport_destroy_stream(grpc_exec_ctx *exec_ctx,
116 grpc_transport *transport,
117 grpc_stream *stream) {
118 transport->vtable->destroy_stream(exec_ctx, transport, stream);
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800119}
120
Craig Tillera82950e2015-09-22 12:33:20 -0700121char *grpc_transport_get_peer(grpc_exec_ctx *exec_ctx,
122 grpc_transport *transport) {
123 return transport->vtable->get_peer(exec_ctx, transport);
Craig Tiller1b22b9d2015-07-20 13:42:22 -0700124}
125
Craig Tillera82950e2015-09-22 12:33:20 -0700126void grpc_transport_stream_op_finish_with_failure(
127 grpc_exec_ctx *exec_ctx, grpc_transport_stream_op *op) {
Craig Tiller6c396862016-01-28 13:53:40 -0800128 grpc_exec_ctx_enqueue(exec_ctx, op->recv_message_ready, false, NULL);
Craig Tillera44cbfc2016-02-03 16:02:49 -0800129 grpc_exec_ctx_enqueue(exec_ctx, op->recv_initial_metadata_ready, false, NULL);
Craig Tiller6c396862016-01-28 13:53:40 -0800130 grpc_exec_ctx_enqueue(exec_ctx, op->on_complete, false, NULL);
Craig Tiller7e320ba2015-04-23 16:28:07 -0700131}
Craig Tiller2ea37fd2015-04-24 13:03:49 -0700132
Craig Tillera82950e2015-09-22 12:33:20 -0700133void grpc_transport_stream_op_add_cancellation(grpc_transport_stream_op *op,
134 grpc_status_code status) {
135 GPR_ASSERT(status != GRPC_STATUS_OK);
136 if (op->cancel_with_status == GRPC_STATUS_OK) {
137 op->cancel_with_status = status;
138 }
139 if (op->close_with_status != GRPC_STATUS_OK) {
140 op->close_with_status = GRPC_STATUS_OK;
141 if (op->optional_close_message != NULL) {
142 gpr_slice_unref(*op->optional_close_message);
143 op->optional_close_message = NULL;
Craig Tiller45ce9272015-07-31 11:22:35 -0700144 }
Craig Tillera82950e2015-09-22 12:33:20 -0700145 }
Craig Tiller2ea37fd2015-04-24 13:03:49 -0700146}
Craig Tiller45ce9272015-07-31 11:22:35 -0700147
Craig Tillera82950e2015-09-22 12:33:20 -0700148typedef struct {
Craig Tiller45ce9272015-07-31 11:22:35 -0700149 gpr_slice message;
Craig Tiller33825112015-09-18 07:44:19 -0700150 grpc_closure *then_call;
151 grpc_closure closure;
Craig Tiller45ce9272015-07-31 11:22:35 -0700152} close_message_data;
153
Craig Tiller6c396862016-01-28 13:53:40 -0800154static void free_message(grpc_exec_ctx *exec_ctx, void *p, bool iomgr_success) {
Craig Tiller45ce9272015-07-31 11:22:35 -0700155 close_message_data *cmd = p;
Craig Tillera82950e2015-09-22 12:33:20 -0700156 gpr_slice_unref(cmd->message);
157 if (cmd->then_call != NULL) {
158 cmd->then_call->cb(exec_ctx, cmd->then_call->cb_arg, iomgr_success);
159 }
160 gpr_free(cmd);
Craig Tiller45ce9272015-07-31 11:22:35 -0700161}
162
Craig Tillera82950e2015-09-22 12:33:20 -0700163void grpc_transport_stream_op_add_close(grpc_transport_stream_op *op,
164 grpc_status_code status,
165 gpr_slice *optional_message) {
Craig Tiller45ce9272015-07-31 11:22:35 -0700166 close_message_data *cmd;
Craig Tillera82950e2015-09-22 12:33:20 -0700167 GPR_ASSERT(status != GRPC_STATUS_OK);
168 if (op->cancel_with_status != GRPC_STATUS_OK ||
169 op->close_with_status != GRPC_STATUS_OK) {
170 if (optional_message) {
171 gpr_slice_unref(*optional_message);
Craig Tiller45ce9272015-07-31 11:22:35 -0700172 }
Craig Tillera82950e2015-09-22 12:33:20 -0700173 return;
174 }
175 if (optional_message) {
176 cmd = gpr_malloc(sizeof(*cmd));
177 cmd->message = *optional_message;
Craig Tiller9d35a1f2015-11-02 14:16:12 -0800178 cmd->then_call = op->on_complete;
Craig Tillera82950e2015-09-22 12:33:20 -0700179 grpc_closure_init(&cmd->closure, free_message, cmd);
Craig Tiller9d35a1f2015-11-02 14:16:12 -0800180 op->on_complete = &cmd->closure;
Craig Tillera82950e2015-09-22 12:33:20 -0700181 op->optional_close_message = &cmd->message;
182 }
Craig Tiller45ce9272015-07-31 11:22:35 -0700183 op->close_with_status = status;
184}