Esempio n. 1
0
/* 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");
  }
}
Esempio n. 2
0
/* tcp read callback */
static void recv_data(void *tp, gpr_slice *slices, size_t nslices,
                      grpc_endpoint_cb_status error) {
  grpc_chttp2_transport *t = tp;
  size_t i;
  int unref = 0;

  switch (error) {
    case GRPC_ENDPOINT_CB_SHUTDOWN:
    case GRPC_ENDPOINT_CB_EOF:
    case GRPC_ENDPOINT_CB_ERROR:
      lock(t);
      drop_connection(t);
      read_error_locked(t);
      unlock(t);
      unref = 1;
      for (i = 0; i < nslices; i++) gpr_slice_unref(slices[i]);
      break;
    case GRPC_ENDPOINT_CB_OK:
      lock(t);
      i = 0;
      GPR_ASSERT(!t->parsing_active);
      if (t->global.error_state == GRPC_CHTTP2_ERROR_STATE_NONE) {
        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 < nslices && grpc_chttp2_perform_read(&t->parsing, slices[i]);
             i++) {
          gpr_slice_unref(slices[i]);
        }
        gpr_mu_lock(&t->mu);
        if (i != nslices) {
          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);
        }
        /* handle higher level things */
        grpc_chttp2_publish_reads(&t->global, &t->parsing);
        t->parsing_active = 0;
      }
      if (i == nslices) {
        grpc_chttp2_schedule_closure(&t->global, &t->reading_action, 1);
      } else {
        read_error_locked(t);
        unref = 1;
      }
      unlock(t);
      for (; i < nslices; i++) gpr_slice_unref(slices[i]);
      break;
  }
  if (unref) {
    UNREF_TRANSPORT(t, "recv_data");
  }
}
Esempio n. 3
0
/* 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();
}