blob: 2ab978be46118ad7d05b2c32e581211f99107daf [file] [log] [blame]
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -08001/*
2 *
Craig Tiller06059952015-02-18 08:34:56 -08003 * Copyright 2015, 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
48 gpr_ref(&refcount->refs);
49}
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)) {
62 grpc_exec_ctx_enqueue(exec_ctx, &refcount->destroy, 1);
63 }
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 Tiller9d35a1f2015-11-02 14:16:12 -0800128 grpc_exec_ctx_enqueue(exec_ctx, op->recv_message_ready, 0);
129 grpc_exec_ctx_enqueue(exec_ctx, op->on_complete, 0);
Craig Tiller7e320ba2015-04-23 16:28:07 -0700130}
Craig Tiller2ea37fd2015-04-24 13:03:49 -0700131
Craig Tillera82950e2015-09-22 12:33:20 -0700132void grpc_transport_stream_op_add_cancellation(grpc_transport_stream_op *op,
133 grpc_status_code status) {
134 GPR_ASSERT(status != GRPC_STATUS_OK);
135 if (op->cancel_with_status == GRPC_STATUS_OK) {
136 op->cancel_with_status = status;
137 }
138 if (op->close_with_status != GRPC_STATUS_OK) {
139 op->close_with_status = GRPC_STATUS_OK;
140 if (op->optional_close_message != NULL) {
141 gpr_slice_unref(*op->optional_close_message);
142 op->optional_close_message = NULL;
Craig Tiller45ce9272015-07-31 11:22:35 -0700143 }
Craig Tillera82950e2015-09-22 12:33:20 -0700144 }
Craig Tiller2ea37fd2015-04-24 13:03:49 -0700145}
Craig Tiller45ce9272015-07-31 11:22:35 -0700146
Craig Tillera82950e2015-09-22 12:33:20 -0700147typedef struct {
Craig Tiller45ce9272015-07-31 11:22:35 -0700148 gpr_slice message;
Craig Tiller33825112015-09-18 07:44:19 -0700149 grpc_closure *then_call;
150 grpc_closure closure;
Craig Tiller45ce9272015-07-31 11:22:35 -0700151} close_message_data;
152
Craig Tillera82950e2015-09-22 12:33:20 -0700153static void free_message(grpc_exec_ctx *exec_ctx, void *p, int iomgr_success) {
Craig Tiller45ce9272015-07-31 11:22:35 -0700154 close_message_data *cmd = p;
Craig Tillera82950e2015-09-22 12:33:20 -0700155 gpr_slice_unref(cmd->message);
156 if (cmd->then_call != NULL) {
157 cmd->then_call->cb(exec_ctx, cmd->then_call->cb_arg, iomgr_success);
158 }
159 gpr_free(cmd);
Craig Tiller45ce9272015-07-31 11:22:35 -0700160}
161
Craig Tillera82950e2015-09-22 12:33:20 -0700162void grpc_transport_stream_op_add_close(grpc_transport_stream_op *op,
163 grpc_status_code status,
164 gpr_slice *optional_message) {
Craig Tiller45ce9272015-07-31 11:22:35 -0700165 close_message_data *cmd;
Craig Tillera82950e2015-09-22 12:33:20 -0700166 GPR_ASSERT(status != GRPC_STATUS_OK);
167 if (op->cancel_with_status != GRPC_STATUS_OK ||
168 op->close_with_status != GRPC_STATUS_OK) {
169 if (optional_message) {
170 gpr_slice_unref(*optional_message);
Craig Tiller45ce9272015-07-31 11:22:35 -0700171 }
Craig Tillera82950e2015-09-22 12:33:20 -0700172 return;
173 }
174 if (optional_message) {
175 cmd = gpr_malloc(sizeof(*cmd));
176 cmd->message = *optional_message;
Craig Tiller9d35a1f2015-11-02 14:16:12 -0800177 cmd->then_call = op->on_complete;
Craig Tillera82950e2015-09-22 12:33:20 -0700178 grpc_closure_init(&cmd->closure, free_message, cmd);
Craig Tiller9d35a1f2015-11-02 14:16:12 -0800179 op->on_complete = &cmd->closure;
Craig Tillera82950e2015-09-22 12:33:20 -0700180 op->optional_close_message = &cmd->message;
181 }
Craig Tiller45ce9272015-07-31 11:22:35 -0700182 op->close_with_status = status;
183}