コード例 #1
0
ファイル: chttp2_transport.c プロジェクト: spietz-handy/grpc
/* tcp read callback */
static void recv_data(grpc_exec_ctx *exec_ctx, void *tp, int success) {
  size_t i;
  int keep_reading = 0;
  grpc_chttp2_transport *t = tp;

  lock(t);
  i = 0;
  GPR_ASSERT(!t->parsing_active);
  if (!t->closed) {
    t->parsing_active = 1;
    /* merge stream lists */
    grpc_chttp2_stream_map_move_into(&t->new_stream_map,
                                     &t->parsing_stream_map);
    grpc_chttp2_prepare_to_read(&t->global, &t->parsing);
    gpr_mu_unlock(&t->mu);
    for (; i < t->read_buffer.count &&
               grpc_chttp2_perform_read(exec_ctx, &t->parsing,
                                        t->read_buffer.slices[i]);
         i++)
      ;
    gpr_mu_lock(&t->mu);
    if (i != t->read_buffer.count) {
      drop_connection(exec_ctx, t);
    }
    /* merge stream lists */
    grpc_chttp2_stream_map_move_into(&t->new_stream_map,
                                     &t->parsing_stream_map);
    t->global.concurrent_stream_count =
        (gpr_uint32)grpc_chttp2_stream_map_size(&t->parsing_stream_map);
    if (t->parsing.initial_window_update != 0) {
      grpc_chttp2_stream_map_for_each(&t->parsing_stream_map,
                                      update_global_window, t);
      t->parsing.initial_window_update = 0;
    }
    /* handle higher level things */
    grpc_chttp2_publish_reads(exec_ctx, &t->global, &t->parsing);
    t->parsing_active = 0;
  }
  if (!success || i != t->read_buffer.count) {
    drop_connection(exec_ctx, t);
    read_error_locked(exec_ctx, t);
  } else if (!t->closed) {
    keep_reading = 1;
    REF_TRANSPORT(t, "keep_reading");
    prevent_endpoint_shutdown(t);
  }
  gpr_slice_buffer_reset_and_unref(&t->read_buffer);
  unlock(exec_ctx, t);

  if (keep_reading) {
    grpc_endpoint_read(exec_ctx, t->ep, &t->read_buffer, &t->recv_data);
    allow_endpoint_shutdown_unlocked(exec_ctx, t);
    UNREF_TRANSPORT(exec_ctx, t, "keep_reading");
  } else {
    UNREF_TRANSPORT(exec_ctx, t, "recv_data");
  }
}
コード例 #2
0
ファイル: chttp2_transport.c プロジェクト: spietz-handy/grpc
static void unlock(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t) {
  unlock_check_read_write_state(exec_ctx, t);
  if (!t->writing_active && !t->closed &&
      grpc_chttp2_unlocking_check_writes(&t->global, &t->writing)) {
    t->writing_active = 1;
    REF_TRANSPORT(t, "writing");
    grpc_exec_ctx_enqueue(exec_ctx, &t->writing_action, 1);
    prevent_endpoint_shutdown(t);
  }

  gpr_mu_unlock(&t->mu);
}
コード例 #3
0
ファイル: chttp2_transport.c プロジェクト: larsonmpdx/grpc
static void unlock(grpc_chttp2_transport *t) {
  grpc_iomgr_closure *run_closures;

  unlock_check_read_write_state(t);
  if (!t->writing_active && !t->closed &&
      grpc_chttp2_unlocking_check_writes(&t->global, &t->writing)) {
    t->writing_active = 1;
    REF_TRANSPORT(t, "writing");
    grpc_chttp2_schedule_closure(&t->global, &t->writing_action, 1);
    prevent_endpoint_shutdown(t);
  }

  run_closures = t->global.pending_closures_head;
  t->global.pending_closures_head = NULL;
  t->global.pending_closures_tail = NULL;

  gpr_mu_unlock(&t->mu);

  while (run_closures) {
    grpc_iomgr_closure *next = run_closures->next;
    run_closures->cb(run_closures->cb_arg, run_closures->success);
    run_closures = next;
  }
}
コード例 #4
0
ファイル: chttp2_transport.c プロジェクト: larsonmpdx/grpc
/* tcp read callback */
static int recv_data_loop(grpc_chttp2_transport *t, int *success) {
  size_t i;
  int keep_reading = 0;

  lock(t);
  i = 0;
  GPR_ASSERT(!t->parsing_active);
  if (!t->closed) {
    t->parsing_active = 1;
    /* merge stream lists */
    grpc_chttp2_stream_map_move_into(&t->new_stream_map,
                                     &t->parsing_stream_map);
    grpc_chttp2_prepare_to_read(&t->global, &t->parsing);
    gpr_mu_unlock(&t->mu);
    for (; i < t->read_buffer.count &&
           grpc_chttp2_perform_read(&t->parsing, t->read_buffer.slices[i]);
         i++)
      ;
    gpr_mu_lock(&t->mu);
    if (i != t->read_buffer.count) {
      drop_connection(t);
    }
    /* merge stream lists */
    grpc_chttp2_stream_map_move_into(&t->new_stream_map,
                                     &t->parsing_stream_map);
    t->global.concurrent_stream_count =
        grpc_chttp2_stream_map_size(&t->parsing_stream_map);
    if (t->parsing.initial_window_update != 0) {
      grpc_chttp2_stream_map_for_each(&t->parsing_stream_map,
                                      update_global_window, t);
      t->parsing.initial_window_update = 0;
    }
    /* handle higher level things */
    grpc_chttp2_publish_reads(&t->global, &t->parsing);
    t->parsing_active = 0;
  }
  if (!*success || i != t->read_buffer.count) {
    drop_connection(t);
    read_error_locked(t);
  } else if (!t->closed) {
    keep_reading = 1;
    REF_TRANSPORT(t, "keep_reading");
    prevent_endpoint_shutdown(t);
  }
  gpr_slice_buffer_reset_and_unref(&t->read_buffer);
  unlock(t);

  if (keep_reading) {
    int ret = -1;
    switch (grpc_endpoint_read(t->ep, &t->read_buffer, &t->recv_data)) {
      case GRPC_ENDPOINT_DONE:
        *success = 1;
        ret = 1;
        break;
      case GRPC_ENDPOINT_ERROR:
        *success = 0;
        ret = 1;
        break;
      case GRPC_ENDPOINT_PENDING:
        ret = 0;
        break;
    }
    allow_endpoint_shutdown_unlocked(t);
    UNREF_TRANSPORT(t, "keep_reading");
    return ret;
  } else {
    UNREF_TRANSPORT(t, "recv_data");
    return 0;
  }

  gpr_log(GPR_ERROR, "should never reach here");
  abort();
}