Exemple #1
0
static void early_out_write_ops(grpc_call *call) {
  switch (call->write_state) {
    case WRITE_STATE_WRITE_CLOSED:
      finish_ioreq_op(call, GRPC_IOREQ_SEND_MESSAGE, GRPC_OP_ERROR);
      finish_ioreq_op(call, GRPC_IOREQ_SEND_STATUS, GRPC_OP_ERROR);
      finish_ioreq_op(call, GRPC_IOREQ_SEND_TRAILING_METADATA, GRPC_OP_ERROR);
      finish_ioreq_op(call, GRPC_IOREQ_SEND_CLOSE, GRPC_OP_OK);
    /* fallthrough */
    case WRITE_STATE_STARTED:
      finish_ioreq_op(call, GRPC_IOREQ_SEND_INITIAL_METADATA, GRPC_OP_ERROR);
    /* fallthrough */
    case WRITE_STATE_INITIAL:
      /* do nothing */
      break;
  }
}
Exemple #2
0
static void finish_send_op(grpc_call *call, grpc_ioreq_op op, write_state ws,
                           grpc_op_error error) {
  lock(call);
  finish_ioreq_op(call, op, error);
  call->sending = 0;
  call->write_state = ws;
  unlock(call);
  grpc_call_internal_unref(call, 0);
}
Exemple #3
0
static void call_on_done_send(void *pc, int success) {
  grpc_call *call = pc;
  lock(call);
  if (call->last_send_contains & (1 << GRPC_IOREQ_SEND_INITIAL_METADATA)) {
    finish_ioreq_op(call, GRPC_IOREQ_SEND_INITIAL_METADATA, success);
  }
  if (call->last_send_contains & (1 << GRPC_IOREQ_SEND_MESSAGE)) {
    finish_ioreq_op(call, GRPC_IOREQ_SEND_MESSAGE, success);
  }
  if (call->last_send_contains & (1 << GRPC_IOREQ_SEND_CLOSE)) {
    finish_ioreq_op(call, GRPC_IOREQ_SEND_TRAILING_METADATA, success);
    finish_ioreq_op(call, GRPC_IOREQ_SEND_STATUS, success);
    finish_ioreq_op(call, GRPC_IOREQ_SEND_CLOSE, 1);
  }
  call->last_send_contains = 0;
  call->sending = 0;
  unlock(call);
  GRPC_CALL_INTERNAL_UNREF(call, "sending", 0);
}
Exemple #4
0
static send_action choose_send_action(grpc_call *call) {
  switch (call->write_state) {
    case WRITE_STATE_INITIAL:
      if (is_op_live(call, GRPC_IOREQ_SEND_INITIAL_METADATA)) {
        if (is_op_live(call, GRPC_IOREQ_SEND_MESSAGE) ||
            is_op_live(call, GRPC_IOREQ_SEND_CLOSE)) {
          return SEND_BUFFERED_INITIAL_METADATA;
        } else {
          return SEND_INITIAL_METADATA;
        }
      }
      return SEND_NOTHING;
    case WRITE_STATE_STARTED:
      if (is_op_live(call, GRPC_IOREQ_SEND_MESSAGE)) {
        if (is_op_live(call, GRPC_IOREQ_SEND_CLOSE)) {
          return SEND_BUFFERED_MESSAGE;
        } else {
          return SEND_MESSAGE;
        }
      } else if (is_op_live(call, GRPC_IOREQ_SEND_CLOSE)) {
        finish_ioreq_op(call, GRPC_IOREQ_SEND_TRAILING_METADATA, GRPC_OP_OK);
        finish_ioreq_op(call, GRPC_IOREQ_SEND_STATUS, GRPC_OP_OK);
        if (call->is_client) {
          return SEND_FINISH;
        } else {
          return SEND_TRAILING_METADATA_AND_FINISH;
        }
      }
      return SEND_NOTHING;
    case WRITE_STATE_WRITE_CLOSED:
      return SEND_NOTHING;
  }
  gpr_log(GPR_ERROR, "should never reach here");
  abort();
  return SEND_NOTHING;
}
Exemple #5
0
static void call_on_done_recv(void *pc, int success) {
  grpc_call *call = pc;
  size_t i;
  GRPC_TIMER_BEGIN(GRPC_PTAG_CALL_ON_DONE_RECV, 0);
  lock(call);
  call->receiving = 0;
  if (success) {
    for (i = 0; success && i < call->recv_ops.nops; i++) {
      grpc_stream_op *op = &call->recv_ops.ops[i];
      switch (op->type) {
        case GRPC_NO_OP:
          break;
        case GRPC_OP_METADATA:
          recv_metadata(call, &op->data.metadata);
          break;
        case GRPC_OP_BEGIN_MESSAGE:
          success = begin_message(call, op->data.begin_message);
          break;
        case GRPC_OP_SLICE:
          success = add_slice_to_message(call, op->data.slice);
          break;
      }
    }
    if (!success) {
      grpc_stream_ops_unref_owned_objects(&call->recv_ops.ops[i],
                                          call->recv_ops.nops - i);
    }
    if (call->recv_state == GRPC_STREAM_RECV_CLOSED) {
      GPR_ASSERT(call->read_state <= READ_STATE_READ_CLOSED);
      call->read_state = READ_STATE_READ_CLOSED;
    }
    if (call->recv_state == GRPC_STREAM_CLOSED) {
      GPR_ASSERT(call->read_state <= READ_STATE_STREAM_CLOSED);
      call->read_state = READ_STATE_STREAM_CLOSED;
      if (call->have_alarm) {
        grpc_alarm_cancel(&call->alarm);
        call->have_alarm = 0;
      }
    }
    finish_read_ops(call);
  } else {
    finish_ioreq_op(call, GRPC_IOREQ_RECV_MESSAGE, 0);
    finish_ioreq_op(call, GRPC_IOREQ_RECV_STATUS, 0);
    finish_ioreq_op(call, GRPC_IOREQ_RECV_CLOSE, 0);
    finish_ioreq_op(call, GRPC_IOREQ_RECV_TRAILING_METADATA, 0);
    finish_ioreq_op(call, GRPC_IOREQ_RECV_INITIAL_METADATA, 0);
    finish_ioreq_op(call, GRPC_IOREQ_RECV_STATUS_DETAILS, 0);
  }
  call->recv_ops.nops = 0;
  unlock(call);

  GRPC_CALL_INTERNAL_UNREF(call, "receiving", 0);
  GRPC_TIMER_BEGIN(GRPC_PTAG_CALL_ON_DONE_RECV, 0);
}
Exemple #6
0
static void finish_read_ops(grpc_call *call) {
  int empty;

  if (is_op_live(call, GRPC_IOREQ_RECV_MESSAGE)) {
    empty =
        (NULL == (*call->request_data[GRPC_IOREQ_RECV_MESSAGE].recv_message =
                      grpc_bbq_pop(&call->incoming_queue)));
    if (!empty) {
      finish_live_ioreq_op(call, GRPC_IOREQ_RECV_MESSAGE, GRPC_OP_OK);
      empty = grpc_bbq_empty(&call->incoming_queue);
    }
  } else {
    empty = grpc_bbq_empty(&call->incoming_queue);
  }

  switch (call->read_state) {
    case READ_STATE_STREAM_CLOSED:
      if (empty) {
        finish_ioreq_op(call, GRPC_IOREQ_RECV_CLOSE, GRPC_OP_OK);
      }
    /* fallthrough */
    case READ_STATE_READ_CLOSED:
      if (empty) {
        finish_ioreq_op(call, GRPC_IOREQ_RECV_MESSAGE, GRPC_OP_OK);
      }
      finish_ioreq_op(call, GRPC_IOREQ_RECV_STATUS, GRPC_OP_OK);
      finish_ioreq_op(call, GRPC_IOREQ_RECV_STATUS_DETAILS, GRPC_OP_OK);
      finish_ioreq_op(call, GRPC_IOREQ_RECV_TRAILING_METADATA, GRPC_OP_OK);
    /* fallthrough */
    case READ_STATE_GOT_INITIAL_METADATA:
      finish_ioreq_op(call, GRPC_IOREQ_RECV_INITIAL_METADATA, GRPC_OP_OK);
    /* fallthrough */
    case READ_STATE_INITIAL:
      /* do nothing */
      break;
  }
}