Nicolas Noble | b7ebd3b | 2014-11-26 16:33:03 -0800 | [diff] [blame] | 1 | /* |
| 2 | * |
Craig Tiller | 0605995 | 2015-02-18 08:34:56 -0800 | [diff] [blame] | 3 | * Copyright 2015, Google Inc. |
Nicolas Noble | b7ebd3b | 2014-11-26 16:33:03 -0800 | [diff] [blame] | 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 | |
Nicolas "Pixel" Noble | 1ff52d5 | 2015-03-01 05:24:36 +0100 | [diff] [blame] | 34 | #ifndef GRPC_INTERNAL_CORE_TRANSPORT_STREAM_OP_H |
| 35 | #define GRPC_INTERNAL_CORE_TRANSPORT_STREAM_OP_H |
Nicolas Noble | b7ebd3b | 2014-11-26 16:33:03 -0800 | [diff] [blame] | 36 | |
| 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 Tiller | e3018e6 | 2015-02-13 17:05:19 -0800 | [diff] [blame] | 43 | /* this many stream ops are inlined into a sopb before allocating */ |
| 44 | #define GRPC_SOPB_INLINE_ELEMENTS 16 |
| 45 | |
Nicolas Noble | b7ebd3b | 2014-11-26 16:33:03 -0800 | [diff] [blame] | 46 | /* Operations that can be performed on a stream. |
| 47 | Used by grpc_stream_op. */ |
| 48 | typedef 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 Noble | b7ebd3b | 2014-11-26 16:33:03 -0800 | [diff] [blame] | 53 | /* 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 */ |
| 64 | typedef 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 */ |
| 72 | typedef struct grpc_flow_ctl_cb { |
| 73 | void (*cb)(void *arg, grpc_op_error error); |
| 74 | void *arg; |
| 75 | } grpc_flow_ctl_cb; |
| 76 | |
Craig Tiller | 205aee1 | 2015-04-16 14:46:41 -0700 | [diff] [blame] | 77 | typedef 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 | |
| 83 | typedef struct grpc_mdelem_list { |
| 84 | grpc_linked_mdelem *head; |
| 85 | grpc_linked_mdelem *tail; |
| 86 | } grpc_mdelem_list; |
| 87 | |
| 88 | typedef struct grpc_metadata_batch { |
| 89 | grpc_mdelem_list list; |
| 90 | grpc_mdelem_list garbage; |
| 91 | gpr_timespec deadline; |
| 92 | } grpc_metadata_batch; |
| 93 | |
| 94 | void grpc_metadata_batch_init(grpc_metadata_batch *comd); |
| 95 | void grpc_metadata_batch_destroy(grpc_metadata_batch *comd); |
| 96 | void grpc_metadata_batch_merge(grpc_metadata_batch *target, |
| 97 | grpc_metadata_batch *add); |
| 98 | |
| 99 | void grpc_metadata_batch_link_head(grpc_metadata_batch *comd, |
| 100 | grpc_linked_mdelem *storage); |
| 101 | void grpc_metadata_batch_link_tail(grpc_metadata_batch *comd, |
| 102 | grpc_linked_mdelem *storage); |
| 103 | |
| 104 | void grpc_metadata_batch_add_head(grpc_metadata_batch *comd, |
| 105 | grpc_linked_mdelem *storage, |
| 106 | grpc_mdelem *elem_to_add); |
| 107 | void grpc_metadata_batch_add_tail(grpc_metadata_batch *comd, |
| 108 | grpc_linked_mdelem *storage, |
| 109 | grpc_mdelem *elem_to_add); |
| 110 | |
| 111 | void 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 Tiller | b116c4f | 2015-04-20 10:07:36 -0700 | [diff] [blame] | 116 | #ifndef NDEBUG |
Craig Tiller | 9c1043e | 2015-04-16 16:20:38 -0700 | [diff] [blame] | 117 | void grpc_metadata_batch_assert_ok(grpc_metadata_batch *comd); |
Craig Tiller | b116c4f | 2015-04-20 10:07:36 -0700 | [diff] [blame] | 118 | #else |
| 119 | #define grpc_metadata_batch_assert_ok(comd) do {} while (0) |
| 120 | #endif |
Craig Tiller | 9c1043e | 2015-04-16 16:20:38 -0700 | [diff] [blame] | 121 | |
Nicolas Noble | b7ebd3b | 2014-11-26 16:33:03 -0800 | [diff] [blame] | 122 | /* Represents a single operation performed on a stream/transport */ |
| 123 | typedef 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 Tiller | 9c1043e | 2015-04-16 16:20:38 -0700 | [diff] [blame] | 130 | grpc_metadata_batch metadata; |
Nicolas Noble | b7ebd3b | 2014-11-26 16:33:03 -0800 | [diff] [blame] | 131 | 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. */ |
| 140 | typedef struct grpc_stream_op_buffer { |
| 141 | grpc_stream_op *ops; |
| 142 | size_t nops; |
| 143 | size_t capacity; |
Craig Tiller | e3018e6 | 2015-02-13 17:05:19 -0800 | [diff] [blame] | 144 | grpc_stream_op inlined_ops[GRPC_SOPB_INLINE_ELEMENTS]; |
Nicolas Noble | b7ebd3b | 2014-11-26 16:33:03 -0800 | [diff] [blame] | 145 | } grpc_stream_op_buffer; |
| 146 | |
| 147 | /* Initialize a stream op buffer */ |
| 148 | void grpc_sopb_init(grpc_stream_op_buffer *sopb); |
| 149 | /* Destroy a stream op buffer */ |
| 150 | void grpc_sopb_destroy(grpc_stream_op_buffer *sopb); |
| 151 | /* Reset a sopb to no elements */ |
| 152 | void grpc_sopb_reset(grpc_stream_op_buffer *sopb); |
Craig Tiller | e3018e6 | 2015-02-13 17:05:19 -0800 | [diff] [blame] | 153 | /* Swap two sopbs */ |
| 154 | void grpc_sopb_swap(grpc_stream_op_buffer *a, grpc_stream_op_buffer *b); |
Nicolas Noble | b7ebd3b | 2014-11-26 16:33:03 -0800 | [diff] [blame] | 155 | |
| 156 | void grpc_stream_ops_unref_owned_objects(grpc_stream_op *ops, size_t nops); |
| 157 | |
| 158 | /* Append a GRPC_NO_OP to a buffer */ |
| 159 | void grpc_sopb_add_no_op(grpc_stream_op_buffer *sopb); |
| 160 | /* Append a GRPC_OP_BEGIN to a buffer */ |
| 161 | void grpc_sopb_add_begin_message(grpc_stream_op_buffer *sopb, gpr_uint32 length, |
| 162 | gpr_uint32 flags); |
Craig Tiller | 9c1043e | 2015-04-16 16:20:38 -0700 | [diff] [blame] | 163 | void grpc_sopb_add_metadata(grpc_stream_op_buffer *sopb, grpc_metadata_batch metadata); |
Nicolas Noble | b7ebd3b | 2014-11-26 16:33:03 -0800 | [diff] [blame] | 164 | /* Append a GRPC_SLICE to a buffer - does not ref/unref the slice */ |
| 165 | void grpc_sopb_add_slice(grpc_stream_op_buffer *sopb, gpr_slice slice); |
| 166 | /* Append a GRPC_OP_FLOW_CTL_CB to a buffer */ |
| 167 | void 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 */ |
| 171 | void grpc_sopb_append(grpc_stream_op_buffer *sopb, grpc_stream_op *ops, |
| 172 | size_t nops); |
| 173 | |
Nicolas "Pixel" Noble | 1ff52d5 | 2015-03-01 05:24:36 +0100 | [diff] [blame] | 174 | #endif /* GRPC_INTERNAL_CORE_TRANSPORT_STREAM_OP_H */ |