LCOV - code coverage report
Current view: top level - src/core/transport/chttp2 - incoming_metadata.c (source / functions) Hit Total Coverage
Test: tmp.zDYK9MVh93 Lines: 84 84 100.0 %
Date: 2015-10-10 Functions: 9 9 100.0 %

          Line data    Source code
       1             : /*
       2             :  *
       3             :  * Copyright 2015, 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             : #include "src/core/transport/chttp2/incoming_metadata.h"
      35             : 
      36             : #include <string.h>
      37             : 
      38             : #include "src/core/transport/chttp2/internal.h"
      39             : 
      40             : #include <grpc/support/alloc.h>
      41             : #include <grpc/support/log.h>
      42             : 
      43     5400327 : void grpc_chttp2_incoming_metadata_buffer_init(
      44             :     grpc_chttp2_incoming_metadata_buffer *buffer) {
      45     5400327 :   buffer->deadline = gpr_inf_future(GPR_CLOCK_REALTIME);
      46     5408465 : }
      47             : 
      48     5403750 : void grpc_chttp2_incoming_metadata_buffer_destroy(
      49             :     grpc_chttp2_incoming_metadata_buffer *buffer) {
      50             :   size_t i;
      51     5673065 :   for (i = 0; i < buffer->count; i++) {
      52      269292 :     GRPC_MDELEM_UNREF(buffer->elems[i].md);
      53             :   }
      54     5403773 :   gpr_free(buffer->elems);
      55     5403863 : }
      56             : 
      57    19113636 : void grpc_chttp2_incoming_metadata_buffer_add(
      58             :     grpc_chttp2_incoming_metadata_buffer *buffer, grpc_mdelem *elem) {
      59    19113636 :   if (buffer->capacity == buffer->count) {
      60     4294677 :     buffer->capacity = GPR_MAX(8, 2 * buffer->capacity);
      61     4294986 :     buffer->elems =
      62     4294677 :         gpr_realloc(buffer->elems, sizeof(*buffer->elems) * buffer->capacity);
      63             :   }
      64    19113945 :   buffer->elems[buffer->count++].md = elem;
      65    19113945 : }
      66             : 
      67        5187 : void grpc_chttp2_incoming_metadata_buffer_set_deadline(
      68             :     grpc_chttp2_incoming_metadata_buffer *buffer, gpr_timespec deadline) {
      69        5187 :   buffer->deadline = deadline;
      70        5187 : }
      71             : 
      72     8040000 : void grpc_chttp2_incoming_metadata_live_op_buffer_end(
      73             :     grpc_chttp2_incoming_metadata_live_op_buffer *buffer) {
      74     8040000 :   gpr_free(buffer->elems);
      75     8042993 :   buffer->elems = NULL;
      76     8042993 : }
      77             : 
      78     4387043 : void grpc_chttp2_incoming_metadata_buffer_place_metadata_batch_into(
      79             :     grpc_chttp2_incoming_metadata_buffer *buffer, grpc_stream_op_buffer *sopb) {
      80             :   grpc_metadata_batch b;
      81             : 
      82     4387043 :   b.list.head = NULL;
      83             :   /* Store away the last element of the list, so that in patch_metadata_ops
      84             :      we can reconstitute the list.
      85             :      We can't do list building here as later incoming metadata may reallocate
      86             :      the underlying array. */
      87     4387043 :   b.list.tail = (void *)(gpr_intptr)buffer->count;
      88     4387043 :   b.garbage.head = b.garbage.tail = NULL;
      89     4387043 :   b.deadline = buffer->deadline;
      90     4387043 :   buffer->deadline = gpr_inf_future(GPR_CLOCK_REALTIME);
      91             : 
      92     4391233 :   grpc_sopb_add_metadata(sopb, b);
      93     4390951 : }
      94             : 
      95     2714973 : void grpc_chttp2_incoming_metadata_buffer_swap(
      96             :     grpc_chttp2_incoming_metadata_buffer *a,
      97             :     grpc_chttp2_incoming_metadata_buffer *b) {
      98     2714973 :   GPR_SWAP(grpc_chttp2_incoming_metadata_buffer, *a, *b);
      99     2714973 : }
     100             : 
     101     4040994 : void grpc_incoming_metadata_buffer_move_to_referencing_sopb(
     102             :     grpc_chttp2_incoming_metadata_buffer *src,
     103             :     grpc_chttp2_incoming_metadata_buffer *dst, grpc_stream_op_buffer *sopb) {
     104             :   size_t delta;
     105             :   size_t i;
     106     4040994 :   dst->deadline = gpr_time_min(src->deadline, dst->deadline);
     107             : 
     108     4041783 :   if (src->count == 0) {
     109     1326799 :     return;
     110             :   }
     111     2714984 :   if (dst->count == 0) {
     112     2714977 :     grpc_chttp2_incoming_metadata_buffer_swap(src, dst);
     113     2712179 :     return;
     114             :   }
     115           7 :   delta = dst->count;
     116           7 :   if (dst->capacity < src->count + dst->count) {
     117           7 :     dst->capacity = GPR_MAX(dst->capacity * 2, src->count + dst->count);
     118           7 :     dst->elems = gpr_realloc(dst->elems, dst->capacity * sizeof(*dst->elems));
     119             :   }
     120           7 :   memcpy(dst->elems + dst->count, src->elems, src->count * sizeof(*src->elems));
     121           7 :   dst->count += src->count;
     122          14 :   for (i = 0; i < sopb->nops; i++) {
     123           7 :     if (sopb->ops[i].type != GRPC_OP_METADATA) continue;
     124          14 :     sopb->ops[i].data.metadata.list.tail =
     125           7 :         (void *)(delta + (gpr_uintptr)sopb->ops[i].data.metadata.list.tail);
     126             :   }
     127           7 :   src->count = 0;
     128             : }
     129             : 
     130     5337698 : void grpc_chttp2_incoming_metadata_buffer_postprocess_sopb_and_begin_live_op(
     131             :     grpc_chttp2_incoming_metadata_buffer *buffer, grpc_stream_op_buffer *sopb,
     132             :     grpc_chttp2_incoming_metadata_live_op_buffer *live_op_buffer) {
     133     5337698 :   grpc_stream_op *ops = sopb->ops;
     134     5337698 :   size_t nops = sopb->nops;
     135             :   size_t i;
     136             :   size_t j;
     137     5337698 :   size_t mdidx = 0;
     138             :   size_t last_mdidx;
     139     5337698 :   int found_metadata = 0;
     140             : 
     141             :   /* rework the array of metadata into a linked list, making use
     142             :      of the breadcrumbs we left in metadata batches during
     143             :      add_metadata_batch */
     144    19498483 :   for (i = 0; i < nops; i++) {
     145    14154547 :     grpc_stream_op *op = &ops[i];
     146    14154547 :     if (op->type != GRPC_OP_METADATA) continue;
     147     4113577 :     found_metadata = 1;
     148             :     /* we left a breadcrumb indicating where the end of this list is,
     149             :        and since we add sequentially, we know from the end of the last
     150             :        segment where this segment begins */
     151     4113577 :     last_mdidx = (size_t)(gpr_intptr)(op->data.metadata.list.tail);
     152     4113577 :     GPR_ASSERT(last_mdidx > mdidx);
     153     4119815 :     GPR_ASSERT(last_mdidx <= buffer->count);
     154             :     /* turn the array into a doubly linked list */
     155     4119815 :     op->data.metadata.list.head = &buffer->elems[mdidx];
     156     4119815 :     op->data.metadata.list.tail = &buffer->elems[last_mdidx - 1];
     157    18831544 :     for (j = mdidx + 1; j < last_mdidx; j++) {
     158    14711729 :       buffer->elems[j].prev = &buffer->elems[j - 1];
     159    14711729 :       buffer->elems[j - 1].next = &buffer->elems[j];
     160             :     }
     161     4119815 :     buffer->elems[mdidx].prev = NULL;
     162     4119815 :     buffer->elems[last_mdidx - 1].next = NULL;
     163             :     /* track where we're up to */
     164     4119815 :     mdidx = last_mdidx;
     165             :   }
     166     5343936 :   if (found_metadata) {
     167     2724701 :     live_op_buffer->elems = buffer->elems;
     168     2724701 :     if (mdidx != buffer->count) {
     169             :       /* we have a partially read metadata batch still in incoming_metadata */
     170           7 :       size_t new_count = buffer->count - mdidx;
     171           7 :       size_t copy_bytes = sizeof(*buffer->elems) * new_count;
     172           7 :       GPR_ASSERT(mdidx < buffer->count);
     173           7 :       buffer->elems = gpr_malloc(copy_bytes);
     174           7 :       memcpy(buffer->elems, live_op_buffer->elems + mdidx, copy_bytes);
     175           7 :       buffer->count = buffer->capacity = new_count;
     176             :     } else {
     177     2724694 :       buffer->elems = NULL;
     178     2724694 :       buffer->count = 0;
     179     2724694 :       buffer->capacity = 0;
     180             :     }
     181             :   }
     182     5343936 : }

Generated by: LCOV version 1.10