blob: 1ca95e7f1a6b99b7b89f22220b91398bd2d1efd7 [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#ifndef __GRPC_INTERNAL_CHANNEL_CHANNEL_STACK_H__
35#define __GRPC_INTERNAL_CHANNEL_CHANNEL_STACK_H__
36
37/* A channel filter defines how operations on a channel are implemented.
38 Channel filters are chained together to create full channels, and if those
39 chains are linear, then channel stacks provide a mechanism to minimize
40 allocations for that chain.
41 Call stacks are created by channel stacks and represent the per-call data
42 for that stack. */
43
44#include <stddef.h>
45
46#include <grpc/grpc.h>
47#include <grpc/support/log.h>
Craig Tiller6e7c6222015-02-20 15:31:21 -080048#include "src/core/debug/trace.h"
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -080049#include "src/core/transport/transport.h"
50
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -080051typedef struct grpc_channel_element grpc_channel_element;
52typedef struct grpc_call_element grpc_call_element;
53
54/* Call operations - things that can be sent and received.
55
56 Threading:
57 SEND, RECV, and CANCEL ops can be active on a call at the same time, but
58 only one SEND, one RECV, and one CANCEL can be active at a time.
59
60 If state is shared between send/receive/cancel operations, it is up to
61 filters to provide their own protection around that. */
62typedef enum {
63 /* send metadata to the channels peer */
64 GRPC_SEND_METADATA,
65 /* send a deadline */
66 GRPC_SEND_DEADLINE,
67 /* start a connection (corresponds to start_invoke/accept) */
68 GRPC_SEND_START,
69 /* send a message to the channels peer */
70 GRPC_SEND_MESSAGE,
Craig Tiller7cfa2d92015-01-19 15:41:49 -080071 /* send a pre-formatted message to the channels peer */
72 GRPC_SEND_PREFORMATTED_MESSAGE,
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -080073 /* send half-close to the channels peer */
74 GRPC_SEND_FINISH,
75 /* request that more data be allowed through flow control */
76 GRPC_REQUEST_DATA,
77 /* metadata was received from the channels peer */
78 GRPC_RECV_METADATA,
79 /* receive a deadline */
80 GRPC_RECV_DEADLINE,
81 /* the end of the first batch of metadata was received */
82 GRPC_RECV_END_OF_INITIAL_METADATA,
83 /* a message was received from the channels peer */
84 GRPC_RECV_MESSAGE,
85 /* half-close was received from the channels peer */
86 GRPC_RECV_HALF_CLOSE,
87 /* full close was received from the channels peer */
88 GRPC_RECV_FINISH,
89 /* the call has been abnormally terminated */
90 GRPC_CANCEL_OP
91} grpc_call_op_type;
92
93/* The direction of the call.
94 The values of the enums (1, -1) matter here - they are used to increment
95 or decrement a pointer to find the next element to call */
96typedef enum { GRPC_CALL_DOWN = 1, GRPC_CALL_UP = -1 } grpc_call_dir;
97
98/* A single filterable operation to be performed on a call */
99typedef struct {
100 /* The type of operation we're performing */
101 grpc_call_op_type type;
102 /* The directionality of this call - does the operation begin at the bottom
103 of the stack and flow up, or does the operation start at the top of the
104 stack and flow down through the filters. */
105 grpc_call_dir dir;
106
107 /* Flags associated with this call: see GRPC_WRITE_* in grpc.h */
108 gpr_uint32 flags;
109
110 /* Argument data, matching up with grpc_call_op_type names */
111 union {
ctillerd79b4862014-12-17 16:36:59 -0800112 struct {
113 grpc_pollset *pollset;
114 } start;
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800115 grpc_byte_buffer *message;
116 grpc_mdelem *metadata;
117 gpr_timespec deadline;
118 } data;
119
120 /* Must be called when processing of this call-op is complete.
121 Signature chosen to match transport flow control callbacks */
122 void (*done_cb)(void *user_data, grpc_op_error error);
123 /* User data to be passed into done_cb */
124 void *user_data;
125} grpc_call_op;
126
127/* returns a string representation of op, that can be destroyed with gpr_free */
128char *grpc_call_op_string(grpc_call_op *op);
129
130typedef enum {
nnoble0c475f02014-12-05 15:37:39 -0800131 /* send a goaway message to remote channels indicating that we are going
132 to disconnect in the future */
133 GRPC_CHANNEL_GOAWAY,
134 /* disconnect any underlying transports */
135 GRPC_CHANNEL_DISCONNECT,
136 /* transport received a new call */
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800137 GRPC_ACCEPT_CALL,
nnoble0c475f02014-12-05 15:37:39 -0800138 /* an underlying transport was closed */
139 GRPC_TRANSPORT_CLOSED,
140 /* an underlying transport is about to be closed */
141 GRPC_TRANSPORT_GOAWAY
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800142} grpc_channel_op_type;
143
144/* A single filterable operation to be performed on a channel */
145typedef struct {
146 /* The type of operation we're performing */
147 grpc_channel_op_type type;
148 /* The directionality of this call - is it bubbling up the stack, or down? */
149 grpc_call_dir dir;
150
151 /* Argument data, matching up with grpc_channel_op_type names */
152 union {
153 struct {
154 grpc_transport *transport;
155 const void *transport_server_data;
156 } accept_call;
nnoble0c475f02014-12-05 15:37:39 -0800157 struct {
158 grpc_status_code status;
159 gpr_slice message;
160 } goaway;
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800161 } data;
162} grpc_channel_op;
163
164/* Channel filters specify:
165 1. the amount of memory needed in the channel & call (via the sizeof_XXX
166 members)
167 2. functions to initialize and destroy channel & call data
168 (init_XXX, destroy_XXX)
169 3. functions to implement call operations and channel operations (call_op,
170 channel_op)
171 4. a name, which is useful when debugging
172
173 Members are laid out in approximate frequency of use order. */
174typedef struct {
175 /* Called to eg. send/receive data on a call.
176 See grpc_call_next_op on how to call the next element in the stack */
ctillerf962f522014-12-10 15:28:27 -0800177 void (*call_op)(grpc_call_element *elem, grpc_call_element *from_elem,
178 grpc_call_op *op);
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800179 /* Called to handle channel level operations - e.g. new calls, or transport
180 closure.
181 See grpc_channel_next_op on how to call the next element in the stack */
ctillerf962f522014-12-10 15:28:27 -0800182 void (*channel_op)(grpc_channel_element *elem,
183 grpc_channel_element *from_elem, grpc_channel_op *op);
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800184
185 /* sizeof(per call data) */
186 size_t sizeof_call_data;
187 /* Initialize per call data.
188 elem is initialized at the start of the call, and elem->call_data is what
189 needs initializing.
190 The filter does not need to do any chaining.
191 server_transport_data is an opaque pointer. If it is NULL, this call is
192 on a client; if it is non-NULL, then it points to memory owned by the
193 transport and is on the server. Most filters want to ignore this
194 argument.*/
195 void (*init_call_elem)(grpc_call_element *elem,
196 const void *server_transport_data);
197 /* Destroy per call data.
198 The filter does not need to do any chaining */
199 void (*destroy_call_elem)(grpc_call_element *elem);
200
201 /* sizeof(per channel data) */
202 size_t sizeof_channel_data;
203 /* Initialize per-channel data.
204 elem is initialized at the start of the call, and elem->channel_data is
205 what needs initializing.
206 is_first, is_last designate this elements position in the stack, and are
207 useful for asserting correct configuration by upper layer code.
208 The filter does not need to do any chaining */
209 void (*init_channel_elem)(grpc_channel_element *elem,
210 const grpc_channel_args *args,
211 grpc_mdctx *metadata_context, int is_first,
212 int is_last);
213 /* Destroy per channel data.
214 The filter does not need to do any chaining */
215 void (*destroy_channel_elem)(grpc_channel_element *elem);
216
217 /* The name of this filter */
218 const char *name;
219} grpc_channel_filter;
220
221/* A channel_element tracks its filter and the filter requested memory within
222 a channel allocation */
223struct grpc_channel_element {
224 const grpc_channel_filter *filter;
225 void *channel_data;
226};
227
228/* A call_element tracks its filter, the filter requested memory within
229 a channel allocation, and the filter requested memory within a call
230 allocation */
231struct grpc_call_element {
232 const grpc_channel_filter *filter;
233 void *channel_data;
234 void *call_data;
235};
236
237/* A channel stack tracks a set of related filters for one channel, and
238 guarantees they live within a single malloc() allocation */
239typedef struct {
240 size_t count;
241 /* Memory required for a call stack (computed at channel stack
242 initialization) */
243 size_t call_stack_size;
244} grpc_channel_stack;
245
246/* A call stack tracks a set of related filters for one call, and guarantees
247 they live within a single malloc() allocation */
Craig Tiller6e7c6222015-02-20 15:31:21 -0800248typedef struct { size_t count; } grpc_call_stack;
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800249
250/* Get a channel element given a channel stack and its index */
251grpc_channel_element *grpc_channel_stack_element(grpc_channel_stack *stack,
252 size_t i);
253/* Get the last channel element in a channel stack */
254grpc_channel_element *grpc_channel_stack_last_element(
255 grpc_channel_stack *stack);
256/* Get a call stack element given a call stack and an index */
257grpc_call_element *grpc_call_stack_element(grpc_call_stack *stack, size_t i);
258
259/* Determine memory required for a channel stack containing a set of filters */
260size_t grpc_channel_stack_size(const grpc_channel_filter **filters,
261 size_t filter_count);
262/* Initialize a channel stack given some filters */
263void grpc_channel_stack_init(const grpc_channel_filter **filters,
264 size_t filter_count, const grpc_channel_args *args,
265 grpc_mdctx *metadata_context,
266 grpc_channel_stack *stack);
267/* Destroy a channel stack */
268void grpc_channel_stack_destroy(grpc_channel_stack *stack);
269
270/* Initialize a call stack given a channel stack. transport_server_data is
271 expected to be NULL on a client, or an opaque transport owned pointer on the
272 server. */
273void grpc_call_stack_init(grpc_channel_stack *channel_stack,
274 const void *transport_server_data,
275 grpc_call_stack *call_stack);
276/* Destroy a call stack */
277void grpc_call_stack_destroy(grpc_call_stack *stack);
278
279/* Call the next operation (depending on call directionality) in a call stack */
280void grpc_call_next_op(grpc_call_element *elem, grpc_call_op *op);
281/* Call the next operation (depending on call directionality) in a channel
282 stack */
283void grpc_channel_next_op(grpc_channel_element *elem, grpc_channel_op *op);
284
285/* Given the top element of a channel stack, get the channel stack itself */
286grpc_channel_stack *grpc_channel_stack_from_top_element(
287 grpc_channel_element *elem);
288/* Given the top element of a call stack, get the call stack itself */
289grpc_call_stack *grpc_call_stack_from_top_element(grpc_call_element *elem);
290
291void grpc_call_log_op(char *file, int line, gpr_log_severity severity,
292 grpc_call_element *elem, grpc_call_op *op);
293
294void grpc_call_element_send_metadata(grpc_call_element *cur_elem,
295 grpc_mdelem *elem);
Craig Tillerd2d0a112015-01-19 16:07:52 -0800296void grpc_call_element_recv_metadata(grpc_call_element *cur_elem,
297 grpc_mdelem *elem);
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800298void grpc_call_element_send_cancel(grpc_call_element *cur_elem);
Craig Tiller6afe2562015-01-19 18:04:23 -0800299void grpc_call_element_send_finish(grpc_call_element *cur_elem);
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800300
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800301#define GRPC_CALL_LOG_OP(sev, elem, op) \
Craig Tiller6e7c6222015-02-20 15:31:21 -0800302 if (grpc_trace_bits & GRPC_TRACE_CHANNEL) grpc_call_log_op(sev, elem, op)
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800303
Craig Tiller190d3602015-02-18 09:23:38 -0800304#endif /* __GRPC_INTERNAL_CHANNEL_CHANNEL_STACK_H__ */