parent
4aa71a1774
commit
5dc3b30964
16 changed files with 541 additions and 313 deletions
@ -0,0 +1,144 @@ |
|||||||
|
/*
|
||||||
|
* |
||||||
|
* Copyright 2015, Google Inc. |
||||||
|
* All rights reserved. |
||||||
|
* |
||||||
|
* Redistribution and use in source and binary forms, with or without |
||||||
|
* modification, are permitted provided that the following conditions are |
||||||
|
* met: |
||||||
|
* |
||||||
|
* * Redistributions of source code must retain the above copyright |
||||||
|
* notice, this list of conditions and the following disclaimer. |
||||||
|
* * Redistributions in binary form must reproduce the above |
||||||
|
* copyright notice, this list of conditions and the following disclaimer |
||||||
|
* in the documentation and/or other materials provided with the |
||||||
|
* distribution. |
||||||
|
* * Neither the name of Google Inc. nor the names of its |
||||||
|
* contributors may be used to endorse or promote products derived from |
||||||
|
* this software without specific prior written permission. |
||||||
|
* |
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
||||||
|
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
||||||
|
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
||||||
|
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
||||||
|
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
||||||
|
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
||||||
|
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
||||||
|
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
||||||
|
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
||||||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
||||||
|
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
||||||
|
* |
||||||
|
*/ |
||||||
|
|
||||||
|
#include "src/core/transport/chttp2/incoming_metadata.h" |
||||||
|
|
||||||
|
#include <string.h> |
||||||
|
|
||||||
|
#include "src/core/transport/chttp2/internal.h" |
||||||
|
|
||||||
|
#include <grpc/support/alloc.h> |
||||||
|
#include <grpc/support/log.h> |
||||||
|
|
||||||
|
void grpc_chttp2_incoming_metadata_buffer_init(grpc_chttp2_incoming_metadata_buffer *buffer) { |
||||||
|
buffer->deadline = gpr_inf_future; |
||||||
|
} |
||||||
|
|
||||||
|
void grpc_chttp2_incoming_metadata_buffer_add(grpc_chttp2_incoming_metadata_buffer *buffer, |
||||||
|
grpc_mdelem *elem) { |
||||||
|
if (buffer->capacity == buffer->count) { |
||||||
|
buffer->capacity = |
||||||
|
GPR_MAX(8, 2 * buffer->capacity); |
||||||
|
buffer->elems = |
||||||
|
gpr_realloc(buffer->elems, |
||||||
|
sizeof(*buffer->elems) * |
||||||
|
buffer->capacity); |
||||||
|
} |
||||||
|
buffer->elems[buffer->count++] |
||||||
|
.md = elem; |
||||||
|
} |
||||||
|
|
||||||
|
void grpc_chttp2_incoming_metadata_buffer_set_deadline(grpc_chttp2_incoming_metadata_buffer *buffer, gpr_timespec deadline) { |
||||||
|
buffer->deadline = deadline; |
||||||
|
} |
||||||
|
|
||||||
|
#if 0 |
||||||
|
void grpc_chttp2_parsing_add_metadata_batch( |
||||||
|
grpc_chttp2_transport_parsing *transport_parsing, |
||||||
|
grpc_chttp2_stream_parsing *stream_parsing) { |
||||||
|
grpc_metadata_batch b; |
||||||
|
|
||||||
|
b.list.head = NULL; |
||||||
|
/* Store away the last element of the list, so that in patch_metadata_ops
|
||||||
|
we can reconstitute the list. |
||||||
|
We can't do list building here as later incoming metadata may reallocate |
||||||
|
the underlying array. */ |
||||||
|
b.list.tail = (void *)(gpr_intptr)stream_parsing->incoming_metadata_count; |
||||||
|
b.garbage.head = b.garbage.tail = NULL; |
||||||
|
b.deadline = stream_parsing->incoming_deadline; |
||||||
|
stream_parsing->incoming_deadline = gpr_inf_future; |
||||||
|
|
||||||
|
grpc_sopb_add_metadata(&stream_parsing->data_parser.incoming_sopb, b); |
||||||
|
} |
||||||
|
#endif |
||||||
|
|
||||||
|
#if 0 |
||||||
|
static void patch_metadata_ops(grpc_chttp2_stream_global *stream_global, |
||||||
|
grpc_chttp2_stream_parsing *stream_parsing) { |
||||||
|
grpc_stream_op *ops = stream_global->incoming_sopb->ops; |
||||||
|
size_t nops = stream_global->incoming_sopb->nops; |
||||||
|
size_t i; |
||||||
|
size_t j; |
||||||
|
size_t mdidx = 0; |
||||||
|
size_t last_mdidx; |
||||||
|
int found_metadata = 0; |
||||||
|
|
||||||
|
/* rework the array of metadata into a linked list, making use
|
||||||
|
of the breadcrumbs we left in metadata batches during |
||||||
|
add_metadata_batch */ |
||||||
|
for (i = 0; i < nops; i++) { |
||||||
|
grpc_stream_op *op = &ops[i]; |
||||||
|
if (op->type != GRPC_OP_METADATA) continue; |
||||||
|
found_metadata = 1; |
||||||
|
/* we left a breadcrumb indicating where the end of this list is,
|
||||||
|
and since we add sequentially, we know from the end of the last |
||||||
|
segment where this segment begins */ |
||||||
|
last_mdidx = (size_t)(gpr_intptr)(op->data.metadata.list.tail); |
||||||
|
GPR_ASSERT(last_mdidx > mdidx); |
||||||
|
GPR_ASSERT(last_mdidx <= stream_parsing->incoming_metadata_count); |
||||||
|
/* turn the array into a doubly linked list */ |
||||||
|
op->data.metadata.list.head = &stream_parsing->incoming_metadata[mdidx]; |
||||||
|
op->data.metadata.list.tail = |
||||||
|
&stream_parsing->incoming_metadata[last_mdidx - 1]; |
||||||
|
for (j = mdidx + 1; j < last_mdidx; j++) { |
||||||
|
stream_parsing->incoming_metadata[j].prev = |
||||||
|
&stream_parsing->incoming_metadata[j - 1]; |
||||||
|
stream_parsing->incoming_metadata[j - 1].next = |
||||||
|
&stream_parsing->incoming_metadata[j]; |
||||||
|
} |
||||||
|
stream_parsing->incoming_metadata[mdidx].prev = NULL; |
||||||
|
stream_parsing->incoming_metadata[last_mdidx - 1].next = NULL; |
||||||
|
/* track where we're up to */ |
||||||
|
mdidx = last_mdidx; |
||||||
|
} |
||||||
|
if (found_metadata) { |
||||||
|
stream_parsing->old_incoming_metadata = stream_parsing->incoming_metadata; |
||||||
|
if (mdidx != stream_parsing->incoming_metadata_count) { |
||||||
|
/* we have a partially read metadata batch still in incoming_metadata */ |
||||||
|
size_t new_count = stream_parsing->incoming_metadata_count - mdidx; |
||||||
|
size_t copy_bytes = |
||||||
|
sizeof(*stream_parsing->incoming_metadata) * new_count; |
||||||
|
GPR_ASSERT(mdidx < stream_parsing->incoming_metadata_count); |
||||||
|
stream_parsing->incoming_metadata = gpr_malloc(copy_bytes); |
||||||
|
memcpy(stream_parsing->old_incoming_metadata + mdidx, |
||||||
|
stream_parsing->incoming_metadata, copy_bytes); |
||||||
|
stream_parsing->incoming_metadata_count = |
||||||
|
stream_parsing->incoming_metadata_capacity = new_count; |
||||||
|
} else { |
||||||
|
stream_parsing->incoming_metadata = NULL; |
||||||
|
stream_parsing->incoming_metadata_count = 0; |
||||||
|
stream_parsing->incoming_metadata_capacity = 0; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
#endif |
@ -0,0 +1,61 @@ |
|||||||
|
/*
|
||||||
|
* |
||||||
|
* Copyright 2015, Google Inc. |
||||||
|
* All rights reserved. |
||||||
|
* |
||||||
|
* Redistribution and use in source and binary forms, with or without |
||||||
|
* modification, are permitted provided that the following conditions are |
||||||
|
* met: |
||||||
|
* |
||||||
|
* * Redistributions of source code must retain the above copyright |
||||||
|
* notice, this list of conditions and the following disclaimer. |
||||||
|
* * Redistributions in binary form must reproduce the above |
||||||
|
* copyright notice, this list of conditions and the following disclaimer |
||||||
|
* in the documentation and/or other materials provided with the |
||||||
|
* distribution. |
||||||
|
* * Neither the name of Google Inc. nor the names of its |
||||||
|
* contributors may be used to endorse or promote products derived from |
||||||
|
* this software without specific prior written permission. |
||||||
|
* |
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
||||||
|
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
||||||
|
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
||||||
|
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
||||||
|
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
||||||
|
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
||||||
|
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
||||||
|
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
||||||
|
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
||||||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
||||||
|
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
||||||
|
* |
||||||
|
*/ |
||||||
|
|
||||||
|
#ifndef GRPC_INTERNAL_CORE_CHTTP2_INCOMING_METADATA_H |
||||||
|
#define GRPC_INTERNAL_CORE_CHTTP2_INCOMING_METADATA_H |
||||||
|
|
||||||
|
#include "src/core/transport/transport.h" |
||||||
|
|
||||||
|
typedef struct { |
||||||
|
grpc_linked_mdelem *elems; |
||||||
|
size_t count; |
||||||
|
size_t capacity; |
||||||
|
gpr_timespec deadline; |
||||||
|
} grpc_chttp2_incoming_metadata_buffer; |
||||||
|
|
||||||
|
/** assumes everything initially zeroed */ |
||||||
|
void grpc_chttp2_incoming_metadata_buffer_init(grpc_chttp2_incoming_metadata_buffer *buffer); |
||||||
|
void grpc_chttp2_incoming_metadata_buffer_destroy(grpc_chttp2_incoming_metadata_buffer *buffer); |
||||||
|
void grpc_chttp2_incoming_metadata_buffer_reset(grpc_chttp2_incoming_metadata_buffer *buffer); |
||||||
|
|
||||||
|
void grpc_chttp2_incoming_metadata_buffer_add(grpc_chttp2_incoming_metadata_buffer *buffer, grpc_mdelem *elem); |
||||||
|
void grpc_chttp2_incoming_metadata_buffer_set_deadline(grpc_chttp2_incoming_metadata_buffer *buffer, gpr_timespec deadline); |
||||||
|
|
||||||
|
/** extend sopb with a metadata batch; this must be post-processed by
|
||||||
|
grpc_chttp2_incoming_metadata_buffer_postprocess_sopb before being handed |
||||||
|
out of the transport */ |
||||||
|
void grpc_chttp2_incoming_metadata_buffer_place_metadata_batch_into(grpc_chttp2_incoming_metadata_buffer *buffer, grpc_stream_op_buffer *sopb); |
||||||
|
|
||||||
|
void grpc_chttp2_incoming_metadata_buffer_postprocess_sopb(grpc_chttp2_incoming_metadata_buffer *buffer, grpc_stream_op_buffer *sopb); |
||||||
|
|
||||||
|
#endif /* GRPC_INTERNAL_CORE_CHTTP2_INCOMING_METADATA_H */ |
@ -0,0 +1,101 @@ |
|||||||
|
/*
|
||||||
|
* |
||||||
|
* Copyright 2015, Google Inc. |
||||||
|
* All rights reserved. |
||||||
|
* |
||||||
|
* Redistribution and use in source and binary forms, with or without |
||||||
|
* modification, are permitted provided that the following conditions are |
||||||
|
* met: |
||||||
|
* |
||||||
|
* * Redistributions of source code must retain the above copyright |
||||||
|
* notice, this list of conditions and the following disclaimer. |
||||||
|
* * Redistributions in binary form must reproduce the above |
||||||
|
* copyright notice, this list of conditions and the following disclaimer |
||||||
|
* in the documentation and/or other materials provided with the |
||||||
|
* distribution. |
||||||
|
* * Neither the name of Google Inc. nor the names of its |
||||||
|
* contributors may be used to endorse or promote products derived from |
||||||
|
* this software without specific prior written permission. |
||||||
|
* |
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
||||||
|
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
||||||
|
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
||||||
|
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
||||||
|
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
||||||
|
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
||||||
|
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
||||||
|
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
||||||
|
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
||||||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
||||||
|
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
||||||
|
* |
||||||
|
*/ |
||||||
|
|
||||||
|
/* core list management */ |
||||||
|
|
||||||
|
static int stream_list_empty(grpc_chttp2_transport *t, |
||||||
|
grpc_chttp2_stream_list_id id) { |
||||||
|
return t->lists[id].head == NULL; |
||||||
|
} |
||||||
|
|
||||||
|
static grpc_chttp2_stream *stream_list_remove_head( |
||||||
|
grpc_chttp2_transport *t, grpc_chttp2_stream_list_id id) { |
||||||
|
grpc_chttp2_stream *s = t->lists[id].head; |
||||||
|
if (s) { |
||||||
|
grpc_chttp2_stream *new_head = s->links[id].next; |
||||||
|
GPR_ASSERT(s->included[id]); |
||||||
|
if (new_head) { |
||||||
|
t->lists[id].head = new_head; |
||||||
|
new_head->links[id].prev = NULL; |
||||||
|
} else { |
||||||
|
t->lists[id].head = NULL; |
||||||
|
t->lists[id].tail = NULL; |
||||||
|
} |
||||||
|
s->included[id] = 0; |
||||||
|
} |
||||||
|
return s; |
||||||
|
} |
||||||
|
|
||||||
|
static void stream_list_remove(grpc_chttp2_transport *t, grpc_chttp2_stream *s, |
||||||
|
grpc_chttp2_stream_list_id id) { |
||||||
|
if (!s->included[id]) return; |
||||||
|
s->included[id] = 0; |
||||||
|
if (s->links[id].prev) { |
||||||
|
s->links[id].prev->links[id].next = s->links[id].next; |
||||||
|
} else { |
||||||
|
GPR_ASSERT(t->lists[id].head == s); |
||||||
|
t->lists[id].head = s->links[id].next; |
||||||
|
} |
||||||
|
if (s->links[id].next) { |
||||||
|
s->links[id].next->links[id].prev = s->links[id].prev; |
||||||
|
} else { |
||||||
|
t->lists[id].tail = s->links[id].prev; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
static void stream_list_add_tail(grpc_chttp2_transport *t, |
||||||
|
grpc_chttp2_stream *s, |
||||||
|
grpc_chttp2_stream_list_id id) { |
||||||
|
grpc_chttp2_stream *old_tail; |
||||||
|
GPR_ASSERT(!s->included[id]); |
||||||
|
old_tail = t->lists[id].tail; |
||||||
|
s->links[id].next = NULL; |
||||||
|
s->links[id].prev = old_tail; |
||||||
|
if (old_tail) { |
||||||
|
old_tail->links[id].next = s; |
||||||
|
} else { |
||||||
|
s->links[id].prev = NULL; |
||||||
|
t->lists[id].head = s; |
||||||
|
} |
||||||
|
t->lists[id].tail = s; |
||||||
|
s->included[id] = 1; |
||||||
|
} |
||||||
|
|
||||||
|
static void stream_list_join(grpc_chttp2_transport *t, grpc_chttp2_stream *s, |
||||||
|
grpc_chttp2_stream_list_id id) { |
||||||
|
if (s->included[id]) { |
||||||
|
return; |
||||||
|
} |
||||||
|
stream_list_add_tail(t, s, id); |
||||||
|
} |
||||||
|
|
File diff suppressed because one or more lines are too long
Loading…
Reference in new issue