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