示例#1
0
文件: call.c 项目: caojiguang/grpc
static void destroy_call(void *call, int ignored_success) {
  size_t i;
  grpc_call *c = call;
  grpc_call_stack_destroy(CALL_STACK_FROM_CALL(c));
  grpc_channel_internal_unref(c->channel);
  gpr_mu_destroy(&c->mu);
  for (i = 0; i < STATUS_SOURCE_COUNT; i++) {
    if (c->status[i].details) {
      grpc_mdstr_unref(c->status[i].details);
    }
  }
  for (i = 0; i < c->owned_metadata_count; i++) {
    grpc_mdelem_unref(c->owned_metadata[i]);
  }
  gpr_free(c->owned_metadata);
  for (i = 0; i < GPR_ARRAY_SIZE(c->buffered_metadata); i++) {
    gpr_free(c->buffered_metadata[i].metadata);
  }
  for (i = 0; i < c->send_initial_metadata_count; i++) {
    grpc_mdelem_unref(c->send_initial_metadata[i].md);
  }
  for (i = 0; i < GRPC_CONTEXT_COUNT; i++) {
    if (c->destroy_context[i]) {
      c->destroy_context[i](c->context[i]);
    }
  }
  grpc_sopb_destroy(&c->send_ops);
  grpc_sopb_destroy(&c->recv_ops);
  grpc_bbq_destroy(&c->incoming_queue);
  gpr_slice_buffer_destroy(&c->incoming_message);
  gpr_free(c);
}
示例#2
0
static void destroy_stream(grpc_exec_ctx *exec_ctx, grpc_transport *gt,
                           grpc_stream *gs) {
  grpc_chttp2_transport *t = (grpc_chttp2_transport *)gt;
  grpc_chttp2_stream *s = (grpc_chttp2_stream *)gs;
  int i;

  gpr_mu_lock(&t->mu);

  GPR_ASSERT(s->global.published_state == GRPC_STREAM_CLOSED ||
             s->global.id == 0);
  GPR_ASSERT(!s->global.in_stream_map);
  if (grpc_chttp2_unregister_stream(t, s) && t->global.sent_goaway) {
    close_transport_locked(exec_ctx, t);
  }
  if (!t->parsing_active && s->global.id) {
    GPR_ASSERT(grpc_chttp2_stream_map_find(&t->parsing_stream_map,
                                           s->global.id) == NULL);
  }

  grpc_chttp2_list_remove_incoming_window_updated(&t->global, &s->global);
  grpc_chttp2_list_remove_writable_stream(&t->global, &s->global);

  gpr_mu_unlock(&t->mu);

  for (i = 0; i < STREAM_LIST_COUNT; i++) {
    if (s->included[i]) {
      gpr_log(GPR_ERROR, "%s stream %d still included in list %d",
              t->global.is_client ? "client" : "server", s->global.id, i);
      abort();
    }
  }

  GPR_ASSERT(s->global.outgoing_sopb == NULL);
  GPR_ASSERT(s->global.publish_sopb == NULL);
  grpc_sopb_destroy(&s->writing.sopb);
  grpc_sopb_destroy(&s->global.incoming_sopb);
  grpc_chttp2_data_parser_destroy(&s->parsing.data_parser);
  grpc_chttp2_incoming_metadata_buffer_destroy(&s->parsing.incoming_metadata);
  grpc_chttp2_incoming_metadata_buffer_destroy(&s->global.incoming_metadata);
  grpc_chttp2_incoming_metadata_live_op_buffer_end(
      &s->global.outstanding_metadata);

  UNREF_TRANSPORT(exec_ctx, t, "stream");
}
示例#3
0
static void run_test(void (*test)(), const char *name) {
  gpr_log(GPR_INFO, "RUN TEST: %s", name);
  g_mdctx = grpc_mdctx_create_with_seed(0);
  grpc_chttp2_hpack_compressor_init(&g_compressor, g_mdctx);
  grpc_sopb_init(&g_sopb);
  test();
  grpc_chttp2_hpack_compressor_destroy(&g_compressor);
  grpc_mdctx_unref(g_mdctx);
  grpc_sopb_destroy(&g_sopb);
}
示例#4
0
static void destroy_stream(grpc_transport *gt, grpc_stream *gs) {
  grpc_chttp2_transport *t = (grpc_chttp2_transport *)gt;
  grpc_chttp2_stream *s = (grpc_chttp2_stream *)gs;
  int i;

  gpr_mu_lock(&t->mu);

  GPR_ASSERT(s->global.published_state == GRPC_STREAM_CLOSED ||
             s->global.id == 0);
  GPR_ASSERT(!s->global.in_stream_map);
  grpc_chttp2_unregister_stream(t, s);
  if (!t->parsing_active && s->global.id) {
    GPR_ASSERT(grpc_chttp2_stream_map_find(&t->parsing_stream_map,
                                           s->global.id) == NULL);
  }

  grpc_chttp2_list_remove_incoming_window_updated(&t->global, &s->global);
  grpc_chttp2_list_remove_writable_window_update_stream(&t->global, &s->global);

  gpr_mu_unlock(&t->mu);

  for (i = 0; i < STREAM_LIST_COUNT; i++) {
    GPR_ASSERT(!s->included[i]);
  }

  GPR_ASSERT(s->global.outgoing_sopb == NULL);
  GPR_ASSERT(s->global.publish_sopb == NULL);
  grpc_sopb_destroy(&s->writing.sopb);
  grpc_sopb_destroy(&s->global.incoming_sopb);
  grpc_chttp2_data_parser_destroy(&s->parsing.data_parser);
  grpc_chttp2_incoming_metadata_buffer_destroy(&s->parsing.incoming_metadata);
  grpc_chttp2_incoming_metadata_buffer_destroy(&s->global.incoming_metadata);
  grpc_chttp2_incoming_metadata_live_op_buffer_end(
      &s->global.outstanding_metadata);

  UNREF_TRANSPORT(t, "stream");
}
示例#5
0
/** Assembles a new grpc_stream_op_buffer with the compressed slices, modifying
 * the associated GRPC_OP_BEGIN_MESSAGE accordingly (new compressed length,
 * flags indicating compression is in effect) and replaces \a send_ops with it.
 * */
static void finish_compressed_sopb(grpc_stream_op_buffer *send_ops,
                                   grpc_call_element *elem) {
  size_t i;
  call_data *calld = elem->call_data;
  int new_slices_added = 0; /* GPR_FALSE */
  grpc_metadata_batch metadata;
  grpc_stream_op_buffer new_send_ops;
  grpc_sopb_init(&new_send_ops);

  for (i = 0; i < send_ops->nops; i++) {
    grpc_stream_op *sop = &send_ops->ops[i];
    switch (sop->type) {
      case GRPC_OP_BEGIN_MESSAGE:
        GPR_ASSERT(calld->slices.length <= GPR_UINT32_MAX);
        grpc_sopb_add_begin_message(
            &new_send_ops, (gpr_uint32)calld->slices.length,
            sop->data.begin_message.flags | GRPC_WRITE_INTERNAL_COMPRESS);
        break;
      case GRPC_OP_SLICE:
        /* Once we reach the slices section of the original buffer, simply add
         * all the new (compressed) slices. We obviously want to do this only
         * once, hence the "new_slices_added" guard. */
        if (!new_slices_added) {
          size_t j;
          for (j = 0; j < calld->slices.count; ++j) {
            grpc_sopb_add_slice(&new_send_ops,
                                gpr_slice_ref(calld->slices.slices[j]));
          }
          new_slices_added = 1; /* GPR_TRUE */
        }
        break;
      case GRPC_OP_METADATA:
        /* move the metadata to the new buffer. */
        grpc_metadata_batch_move(&metadata, &sop->data.metadata);
        grpc_sopb_add_metadata(&new_send_ops, metadata);
        break;
      case GRPC_NO_OP:
        break;
    }
  }
  grpc_sopb_swap(send_ops, &new_send_ops);
  grpc_sopb_destroy(&new_send_ops);
}
示例#6
0
static void test_decode_random_headers_inner(int max_len) {
  int i;
  test_decode_random_header_state st;
  gpr_slice_buffer output;
  gpr_slice merged;
  grpc_stream_op_buffer encops;
  grpc_chttp2_hpack_parser parser;

  grpc_chttp2_hpack_parser_init(&parser, g_mdctx);
  grpc_sopb_init(&encops);

  gpr_log(GPR_INFO, "max_len = %d", max_len);

  for (i = 0; i < 10000; i++) {
    randstr(st.key, max_len);
    randstr(st.value, max_len);

    add_sopb_headers(1, st.key, st.value);
    gpr_slice_buffer_init(&output);
    GPR_ASSERT(0 ==
               grpc_chttp2_preencode(g_sopb.ops, &g_sopb.nops, 0, &encops));
    grpc_chttp2_encode(encops.ops, encops.nops, 0, 0xdeadbeef, &g_compressor,
                       &output);
    encops.nops = 0;
    merged = grpc_slice_merge(output.slices, output.count);
    gpr_slice_buffer_destroy(&output);

    st.got_hdr = 0;
    parser.on_header = chk_hdr;
    parser.on_header_user_data = &st;
    grpc_chttp2_hpack_parser_parse(&parser, GPR_SLICE_START_PTR(merged) + 9,
                                   GPR_SLICE_END_PTR(merged));
    GPR_ASSERT(st.got_hdr);

    gpr_slice_unref(merged);
  }

  grpc_chttp2_hpack_parser_destroy(&parser);
  grpc_sopb_destroy(&encops);
}
示例#7
0
/* verify that the output generated by encoding the stream matches the
   hexstring passed in */
static void verify_sopb(size_t window_available, int eof,
                        size_t expect_window_used, const char *expected) {
  gpr_slice_buffer output;
  grpc_stream_op_buffer encops;
  gpr_slice merged;
  gpr_slice expect = parse_hexstring(expected);
  gpr_slice_buffer_init(&output);
  grpc_sopb_init(&encops);
  GPR_ASSERT(expect_window_used ==
             grpc_chttp2_preencode(g_sopb.ops, &g_sopb.nops, window_available,
                                   &encops));
  grpc_chttp2_encode(encops.ops, encops.nops, eof, 0xdeadbeef, &g_compressor,
                     &output);
  encops.nops = 0;
  merged = grpc_slice_merge(output.slices, output.count);
  gpr_slice_buffer_destroy(&output);
  grpc_sopb_destroy(&encops);

  if (0 != gpr_slice_cmp(merged, expect)) {
    char *expect_str =
        gpr_hexdump((char *)GPR_SLICE_START_PTR(expect),
                    GPR_SLICE_LENGTH(expect), GPR_HEXDUMP_PLAINTEXT);
    char *got_str =
        gpr_hexdump((char *)GPR_SLICE_START_PTR(merged),
                    GPR_SLICE_LENGTH(merged), GPR_HEXDUMP_PLAINTEXT);
    gpr_log(GPR_ERROR, "mismatched output for %s", expected);
    gpr_log(GPR_ERROR, "EXPECT: %s", expect_str);
    gpr_log(GPR_ERROR, "GOT:    %s", got_str);
    gpr_free(expect_str);
    gpr_free(got_str);
    g_failure = 1;
  }

  gpr_slice_unref(merged);
  gpr_slice_unref(expect);
}
示例#8
0
void grpc_chttp2_data_parser_destroy(grpc_chttp2_data_parser *parser) {
  grpc_sopb_destroy(&parser->incoming_sopb);
}
示例#9
0
int main(int argc, char **argv) {
  /* some basic test data */
  gpr_slice test_slice_1 = gpr_slice_malloc(1);
  gpr_slice test_slice_2 = gpr_slice_malloc(2);
  gpr_slice test_slice_3 = gpr_slice_malloc(3);
  gpr_slice test_slice_4 = gpr_slice_malloc(4);
  unsigned i;

  grpc_stream_op_buffer buf;
  grpc_stream_op_buffer buf2;

  grpc_test_init(argc, argv);
  /* initialize one of our buffers */
  grpc_sopb_init(&buf);
  /* it should start out empty */
  GPR_ASSERT(buf.nops == 0);

  /* add some data to the buffer */
  grpc_sopb_add_begin_message(&buf, 1, 2);
  grpc_sopb_add_slice(&buf, test_slice_1);
  grpc_sopb_add_slice(&buf, test_slice_2);
  grpc_sopb_add_slice(&buf, test_slice_3);
  grpc_sopb_add_slice(&buf, test_slice_4);
  grpc_sopb_add_no_op(&buf);

  /* verify that the data went in ok */
  GPR_ASSERT(buf.nops == 6);
  GPR_ASSERT(buf.ops[0].type == GRPC_OP_BEGIN_MESSAGE);
  GPR_ASSERT(buf.ops[0].data.begin_message.length == 1);
  GPR_ASSERT(buf.ops[0].data.begin_message.flags == 2);
  GPR_ASSERT(buf.ops[1].type == GRPC_OP_SLICE);
  assert_slices_equal(buf.ops[1].data.slice, test_slice_1);
  GPR_ASSERT(buf.ops[2].type == GRPC_OP_SLICE);
  assert_slices_equal(buf.ops[2].data.slice, test_slice_2);
  GPR_ASSERT(buf.ops[3].type == GRPC_OP_SLICE);
  assert_slices_equal(buf.ops[3].data.slice, test_slice_3);
  GPR_ASSERT(buf.ops[4].type == GRPC_OP_SLICE);
  assert_slices_equal(buf.ops[4].data.slice, test_slice_4);
  GPR_ASSERT(buf.ops[5].type == GRPC_NO_OP);

  /* initialize the second buffer */
  grpc_sopb_init(&buf2);
  /* add a no-op, and then the original buffer */
  grpc_sopb_add_no_op(&buf2);
  grpc_sopb_append(&buf2, buf.ops, buf.nops);
  /* should be one element bigger than the original */
  GPR_ASSERT(buf2.nops == buf.nops + 1);
  GPR_ASSERT(buf2.ops[0].type == GRPC_NO_OP);
  /* and the tail should be the same */
  for (i = 0; i < buf.nops; i++) {
    GPR_ASSERT(buf2.ops[i + 1].type == buf.ops[i].type);
  }

  /* destroy the buffers */
  grpc_sopb_destroy(&buf);
  grpc_sopb_destroy(&buf2);

  gpr_slice_unref(test_slice_1);
  gpr_slice_unref(test_slice_2);
  gpr_slice_unref(test_slice_3);
  gpr_slice_unref(test_slice_4);

  return 0;
}