コード例 #1
0
ファイル: call.c プロジェクト: qioixiy/grpc
static void unlock(grpc_call *call) {
  send_action sa = SEND_NOTHING;
  completed_request completed_requests[GRPC_IOREQ_OP_COUNT];
  int completing_requests = 0;
  int need_more_data =
      call->need_more_data &&
      (call->write_state >= WRITE_STATE_STARTED || !call->is_client);
  int i;

  if (need_more_data) {
    call->need_more_data = 0;
  }

  if (!call->completing && call->num_completed_requests != 0) {
    completing_requests = call->num_completed_requests;
    memcpy(completed_requests, call->completed_requests,
           sizeof(completed_requests));
    call->num_completed_requests = 0;
    call->completing = 1;
    grpc_call_internal_ref(call);
  }

  if (!call->sending) {
    sa = choose_send_action(call);
    if (sa != SEND_NOTHING) {
      call->sending = 1;
      grpc_call_internal_ref(call);
    }
  }

  gpr_mu_unlock(&call->mu);

  if (need_more_data) {
    request_more_data(call);
  }

  if (sa != SEND_NOTHING) {
    enact_send_action(call, sa);
  }

  if (completing_requests > 0) {
    for (i = 0; i < completing_requests; i++) {
      completed_requests[i].on_complete(call, completed_requests[i].status,
                                        completed_requests[i].user_data);
    }
    lock(call);
    call->completing = 0;
    unlock(call);
    grpc_call_internal_unref(call, 0);
  }
}
コード例 #2
0
ファイル: completion_queue.c プロジェクト: AddictXQ/grpc
void grpc_cq_begin_op(grpc_completion_queue *cc, grpc_call *call,
                      grpc_completion_type type) {
  gpr_ref(&cc->refs);
  if (call) grpc_call_internal_ref(call);
#ifndef NDEBUG
  gpr_atm_no_barrier_fetch_add(&cc->pending_op_count[type], 1);
#endif
}
コード例 #3
0
ファイル: call.c プロジェクト: qioixiy/grpc
void grpc_call_set_deadline(grpc_call_element *elem, gpr_timespec deadline) {
  grpc_call *call = CALL_FROM_TOP_ELEM(elem);

  if (call->have_alarm) {
    gpr_log(GPR_ERROR, "Attempt to set deadline alarm twice");
  }
  grpc_call_internal_ref(call);
  call->have_alarm = 1;
  grpc_alarm_init(&call->alarm, deadline, call_alarm, call, gpr_now());
}
コード例 #4
0
ファイル: server.c プロジェクト: mindis/grpc
static void begin_call(grpc_server *server, call_data *calld,
                       requested_call *rc) {
  grpc_ioreq_completion_func publish = publish_was_not_set;
  grpc_ioreq req[2];
  grpc_ioreq *r = req;

  /* called once initial metadata has been read by the call, but BEFORE
     the ioreq to fetch it out of the call has been executed.
     This means metadata related fields can be relied on in calld, but to
     fill in the metadata array passed by the client, we need to perform
     an ioreq op, that should complete immediately. */

  switch (rc->type) {
    case LEGACY_CALL:
      calld->legacy = gpr_malloc(sizeof(legacy_data));
      memset(calld->legacy, 0, sizeof(legacy_data));
      r->op = GRPC_IOREQ_RECV_INITIAL_METADATA;
      r->data.recv_metadata = &calld->legacy->initial_metadata;
      r++;
      publish = publish_legacy;
      break;
    case BATCH_CALL:
      cpstr(&rc->data.batch.details->host,
            &rc->data.batch.details->host_capacity, calld->host);
      cpstr(&rc->data.batch.details->method,
            &rc->data.batch.details->method_capacity, calld->path);
      grpc_call_set_completion_queue(calld->call, rc->data.batch.cq_bind);
      *rc->data.batch.call = calld->call;
      r->op = GRPC_IOREQ_RECV_INITIAL_METADATA;
      r->data.recv_metadata = rc->data.batch.initial_metadata;
      r++;
      calld->cq_new = server->unregistered_cq;
      publish = publish_registered_or_batch;
      break;
    case REGISTERED_CALL:
      *rc->data.registered.deadline = calld->deadline;
      grpc_call_set_completion_queue(calld->call, rc->data.registered.cq_bind);
      *rc->data.registered.call = calld->call;
      r->op = GRPC_IOREQ_RECV_INITIAL_METADATA;
      r->data.recv_metadata = rc->data.registered.initial_metadata;
      r++;
      if (rc->data.registered.optional_payload) {
        r->op = GRPC_IOREQ_RECV_MESSAGE;
        r->data.recv_message = rc->data.registered.optional_payload;
        r++;
      }
      calld->cq_new = rc->data.registered.registered_method->cq;
      publish = publish_registered_or_batch;
      break;
  }

  grpc_call_internal_ref(calld->call);
  grpc_call_start_ioreq_and_call_back(calld->call, req, r - req, publish,
                                      rc->tag);
}