blob: 20146b9af212a277d8243c38ba3ee011fe631d98 [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
Nicolas "Pixel" Noble1ff52d52015-03-01 05:24:36 +010034#ifndef GRPC_INTERNAL_CORE_TRANSPORT_STREAM_OP_H
35#define GRPC_INTERNAL_CORE_TRANSPORT_STREAM_OP_H
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -080036
37#include <grpc/grpc.h>
38#include <grpc/support/port_platform.h>
39#include <grpc/support/slice.h>
40#include <grpc/support/time.h>
41#include "src/core/transport/metadata.h"
42
Craig Tillere3018e62015-02-13 17:05:19 -080043/* this many stream ops are inlined into a sopb before allocating */
44#define GRPC_SOPB_INLINE_ELEMENTS 16
45
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -080046/* Operations that can be performed on a stream.
47 Used by grpc_stream_op. */
48typedef enum grpc_stream_op_code {
49 /* Do nothing code. Useful if rewriting a batch to exclude some operations.
50 Must be ignored by receivers */
51 GRPC_NO_OP,
52 GRPC_OP_METADATA,
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -080053 /* Begin a message/metadata element/status - as defined by
54 grpc_message_type. */
55 GRPC_OP_BEGIN_MESSAGE,
56 /* Add a slice of data to the current message/metadata element/status.
57 Must not overflow the forward declared length. */
58 GRPC_OP_SLICE,
59 /* Call some function once this operation has passed flow control. */
60 GRPC_OP_FLOW_CTL_CB
61} grpc_stream_op_code;
62
63/* Arguments for GRPC_OP_BEGIN */
64typedef struct grpc_begin_message {
65 /* How many bytes of data will this message contain */
66 gpr_uint32 length;
67 /* Write flags for the message: see grpc.h GRPC_WRITE_xxx */
68 gpr_uint32 flags;
69} grpc_begin_message;
70
71/* Arguments for GRPC_OP_FLOW_CTL_CB */
72typedef struct grpc_flow_ctl_cb {
73 void (*cb)(void *arg, grpc_op_error error);
74 void *arg;
75} grpc_flow_ctl_cb;
76
Craig Tiller205aee12015-04-16 14:46:41 -070077typedef struct grpc_linked_mdelem {
78 grpc_mdelem *md;
79 struct grpc_linked_mdelem *next;
80 struct grpc_linked_mdelem *prev;
81} grpc_linked_mdelem;
82
83typedef struct grpc_mdelem_list {
84 grpc_linked_mdelem *head;
85 grpc_linked_mdelem *tail;
86} grpc_mdelem_list;
87
88typedef struct grpc_metadata_batch {
89 grpc_mdelem_list list;
90 grpc_mdelem_list garbage;
91 gpr_timespec deadline;
92} grpc_metadata_batch;
93
94void grpc_metadata_batch_init(grpc_metadata_batch *comd);
95void grpc_metadata_batch_destroy(grpc_metadata_batch *comd);
96void grpc_metadata_batch_merge(grpc_metadata_batch *target,
97 grpc_metadata_batch *add);
98
99void grpc_metadata_batch_link_head(grpc_metadata_batch *comd,
100 grpc_linked_mdelem *storage);
101void grpc_metadata_batch_link_tail(grpc_metadata_batch *comd,
102 grpc_linked_mdelem *storage);
103
104void grpc_metadata_batch_add_head(grpc_metadata_batch *comd,
105 grpc_linked_mdelem *storage,
106 grpc_mdelem *elem_to_add);
107void grpc_metadata_batch_add_tail(grpc_metadata_batch *comd,
108 grpc_linked_mdelem *storage,
109 grpc_mdelem *elem_to_add);
110
111void grpc_metadata_batch_filter(grpc_metadata_batch *comd,
112 grpc_mdelem *(*filter)(void *user_data,
113 grpc_mdelem *elem),
114 void *user_data);
115
Craig Tillerb116c4f2015-04-20 10:07:36 -0700116#ifndef NDEBUG
Craig Tiller9c1043e2015-04-16 16:20:38 -0700117void grpc_metadata_batch_assert_ok(grpc_metadata_batch *comd);
Craig Tillerb116c4f2015-04-20 10:07:36 -0700118#else
119#define grpc_metadata_batch_assert_ok(comd) do {} while (0)
120#endif
Craig Tiller9c1043e2015-04-16 16:20:38 -0700121
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800122/* Represents a single operation performed on a stream/transport */
123typedef struct grpc_stream_op {
124 /* the operation to be applied */
125 enum grpc_stream_op_code type;
126 /* the arguments to this operation. union fields are named according to the
127 associated op-code */
128 union {
129 grpc_begin_message begin_message;
Craig Tiller9c1043e2015-04-16 16:20:38 -0700130 grpc_metadata_batch metadata;
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800131 gpr_slice slice;
132 grpc_flow_ctl_cb flow_ctl_cb;
133 } data;
134} grpc_stream_op;
135
136/* A stream op buffer is a wrapper around stream operations that is dynamically
137 extendable.
138 TODO(ctiller): inline a few elements into the struct, to avoid common case
139 per-call allocations. */
140typedef struct grpc_stream_op_buffer {
141 grpc_stream_op *ops;
142 size_t nops;
143 size_t capacity;
Craig Tillere3018e62015-02-13 17:05:19 -0800144 grpc_stream_op inlined_ops[GRPC_SOPB_INLINE_ELEMENTS];
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800145} grpc_stream_op_buffer;
146
147/* Initialize a stream op buffer */
148void grpc_sopb_init(grpc_stream_op_buffer *sopb);
149/* Destroy a stream op buffer */
150void grpc_sopb_destroy(grpc_stream_op_buffer *sopb);
151/* Reset a sopb to no elements */
152void grpc_sopb_reset(grpc_stream_op_buffer *sopb);
Craig Tillere3018e62015-02-13 17:05:19 -0800153/* Swap two sopbs */
154void grpc_sopb_swap(grpc_stream_op_buffer *a, grpc_stream_op_buffer *b);
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800155
156void grpc_stream_ops_unref_owned_objects(grpc_stream_op *ops, size_t nops);
157
158/* Append a GRPC_NO_OP to a buffer */
159void grpc_sopb_add_no_op(grpc_stream_op_buffer *sopb);
160/* Append a GRPC_OP_BEGIN to a buffer */
161void grpc_sopb_add_begin_message(grpc_stream_op_buffer *sopb, gpr_uint32 length,
162 gpr_uint32 flags);
Craig Tiller9c1043e2015-04-16 16:20:38 -0700163void grpc_sopb_add_metadata(grpc_stream_op_buffer *sopb, grpc_metadata_batch metadata);
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800164/* Append a GRPC_SLICE to a buffer - does not ref/unref the slice */
165void grpc_sopb_add_slice(grpc_stream_op_buffer *sopb, gpr_slice slice);
166/* Append a GRPC_OP_FLOW_CTL_CB to a buffer */
167void grpc_sopb_add_flow_ctl_cb(grpc_stream_op_buffer *sopb,
168 void (*cb)(void *arg, grpc_op_error error),
169 void *arg);
170/* Append a buffer to a buffer - does not ref/unref any internal objects */
171void grpc_sopb_append(grpc_stream_op_buffer *sopb, grpc_stream_op *ops,
172 size_t nops);
173
Nicolas "Pixel" Noble1ff52d52015-03-01 05:24:36 +0100174#endif /* GRPC_INTERNAL_CORE_TRANSPORT_STREAM_OP_H */