Esempio n. 1
0
static void test_pluck(void) {
  grpc_event *ev;
  grpc_completion_queue *cc;
  void *tags[128];
  unsigned i, j;
  int on_finish_called = 0;

  LOG_TEST();

  for (i = 0; i < GPR_ARRAY_SIZE(tags); i++) {
    tags[i] = create_test_tag();
    for (j = 0; j < i; j++) {
      GPR_ASSERT(tags[i] != tags[j]);
    }
  }

  cc = grpc_completion_queue_create();

  for (i = 0; i < GPR_ARRAY_SIZE(tags); i++) {
    grpc_cq_begin_op(cc, NULL, GRPC_OP_COMPLETE);
    grpc_cq_end_op(cc, tags[i], NULL, increment_int_on_finish,
                   &on_finish_called, GRPC_OP_OK);
  }

  for (i = 0; i < GPR_ARRAY_SIZE(tags); i++) {
    ev = grpc_completion_queue_pluck(cc, tags[i], gpr_inf_past);
    GPR_ASSERT(ev->tag == tags[i]);
    grpc_event_finish(ev);
  }

  GPR_ASSERT(on_finish_called == GPR_ARRAY_SIZE(tags));

  for (i = 0; i < GPR_ARRAY_SIZE(tags); i++) {
    grpc_cq_begin_op(cc, NULL, GRPC_OP_COMPLETE);
    grpc_cq_end_op(cc, tags[i], NULL, increment_int_on_finish,
                   &on_finish_called, GRPC_OP_OK);
  }

  for (i = 0; i < GPR_ARRAY_SIZE(tags); i++) {
    ev = grpc_completion_queue_pluck(cc, tags[GPR_ARRAY_SIZE(tags) - i - 1],
                                     gpr_inf_past);
    GPR_ASSERT(ev->tag == tags[GPR_ARRAY_SIZE(tags) - i - 1]);
    grpc_event_finish(ev);
  }

  GPR_ASSERT(on_finish_called == 2 * GPR_ARRAY_SIZE(tags));

  shutdown_and_destroy(cc);
}
Esempio n. 2
0
static void destroy_call_elem(grpc_call_element *elem) {
  channel_data *chand = elem->channel_data;
  call_data *calld = elem->call_data;
  size_t i, j;

  gpr_mu_lock(&chand->server->mu);
  for (i = 0; i < CALL_LIST_COUNT; i++) {
    call_list_remove(elem->call_data, i);
  }
  if (chand->server->shutdown && chand->server->lists[ALL_CALLS] == NULL) {
    for (i = 0; i < chand->server->num_shutdown_tags; i++) {
      for (j = 0; j < chand->server->cq_count; j++) {
        grpc_cq_end_op(chand->server->cqs[j], chand->server->shutdown_tags[i],
                       NULL, 1);
      }
    }
  }
  gpr_mu_unlock(&chand->server->mu);

  if (calld->host) {
    grpc_mdstr_unref(calld->host);
  }
  if (calld->path) {
    grpc_mdstr_unref(calld->path);
  }

  server_unref(chand->server);
}
Esempio n. 3
0
static void maybe_finish_shutdown(grpc_server *server) {
  size_t i;
  if (!server->shutdown || server->shutdown_published) {
    return;
  }

  gpr_mu_lock(&server->mu_call);
  if (server->lists[ALL_CALLS] != NULL) {
    gpr_log(GPR_DEBUG,
            "Waiting for all calls to finish before destroying server");
    gpr_mu_unlock(&server->mu_call);
    return;
  }
  gpr_mu_unlock(&server->mu_call);

  if (server->root_channel_data.next != &server->root_channel_data) {
    gpr_log(GPR_DEBUG,
            "Waiting for all channels to close before destroying server");
    return;
  }
  if (server->listeners_destroyed < num_listeners(server)) {
    gpr_log(GPR_DEBUG, "Waiting for all listeners to be destroyed (@ %d/%d)",
            server->listeners_destroyed, num_listeners(server));
    return;
  }
  server->shutdown_published = 1;
  for (i = 0; i < server->num_shutdown_tags; i++) {
    grpc_cq_end_op(server->shutdown_tags[i].cq, server->shutdown_tags[i].tag,
                   NULL, 1);
  }
}
Esempio n. 4
0
static void publish_registered_or_batch(grpc_call *call, int success,
                                        void *tag) {
  grpc_call_element *elem =
      grpc_call_stack_element(grpc_call_get_call_stack(call), 0);
  call_data *calld = elem->call_data;
  grpc_cq_end_op(calld->cq_new, tag, call, success);
}
Esempio n. 5
0
static void maybe_finish_shutdown(grpc_exec_ctx *exec_ctx,
                                  grpc_server *server) {
  size_t i;
  if (!gpr_atm_acq_load(&server->shutdown_flag) || server->shutdown_published) {
    return;
  }

  kill_pending_work_locked(exec_ctx, server,
                           GRPC_ERROR_CREATE("Server Shutdown"));

  if (server->root_channel_data.next != &server->root_channel_data ||
      server->listeners_destroyed < num_listeners(server)) {
    if (gpr_time_cmp(gpr_time_sub(gpr_now(GPR_CLOCK_REALTIME),
                                  server->last_shutdown_message_time),
                     gpr_time_from_seconds(1, GPR_TIMESPAN)) >= 0) {
      server->last_shutdown_message_time = gpr_now(GPR_CLOCK_REALTIME);
      gpr_log(GPR_DEBUG,
              "Waiting for %d channels and %d/%d listeners to be destroyed"
              " before shutting down server",
              num_channels(server),
              num_listeners(server) - server->listeners_destroyed,
              num_listeners(server));
    }
    return;
  }
  server->shutdown_published = 1;
  for (i = 0; i < server->num_shutdown_tags; i++) {
    server_ref(server);
    grpc_cq_end_op(exec_ctx, server->shutdown_tags[i].cq,
                   server->shutdown_tags[i].tag, GRPC_ERROR_NONE,
                   done_shutdown_event, server,
                   &server->shutdown_tags[i].completion);
  }
}
Esempio n. 6
0
static void producer_thread(void *arg) {
  test_thread_options *opt = arg;
  int i;

  gpr_log(GPR_INFO, "producer %d started", opt->id);
  gpr_event_set(&opt->on_started, (void *)(gpr_intptr)1);
  GPR_ASSERT(gpr_event_wait(opt->phase1, ten_seconds_time()));

  gpr_log(GPR_INFO, "producer %d phase 1", opt->id);
  for (i = 0; i < TEST_THREAD_EVENTS; i++) {
    grpc_cq_begin_op(opt->cc);
  }

  gpr_log(GPR_INFO, "producer %d phase 1 done", opt->id);
  gpr_event_set(&opt->on_phase1_done, (void *)(gpr_intptr)1);
  GPR_ASSERT(gpr_event_wait(opt->phase2, ten_seconds_time()));

  gpr_log(GPR_INFO, "producer %d phase 2", opt->id);
  for (i = 0; i < TEST_THREAD_EVENTS; i++) {
    grpc_cq_end_op(opt->cc, (void *)(gpr_intptr)1, 1, free_completion, NULL,
                   gpr_malloc(sizeof(grpc_cq_completion)));
    opt->events_triggered++;
  }

  gpr_log(GPR_INFO, "producer %d phase 2 done", opt->id);
  gpr_event_set(&opt->on_finished, (void *)(gpr_intptr)1);
}
Esempio n. 7
0
static void test_cq_end_op(void) {
  grpc_event *ev;
  grpc_completion_queue *cc;
  int on_finish_called = 0;
  void *tag = create_test_tag();

  LOG_TEST();

  cc = grpc_completion_queue_create();

  grpc_cq_begin_op(cc, NULL, GRPC_OP_COMPLETE);
  grpc_cq_end_op(cc, tag, NULL, increment_int_on_finish, &on_finish_called,
                 GRPC_OP_OK);

  ev = grpc_completion_queue_next(cc, gpr_inf_past);
  GPR_ASSERT(ev != NULL);
  GPR_ASSERT(ev->type == GRPC_OP_COMPLETE);
  GPR_ASSERT(ev->tag == tag);
  GPR_ASSERT(ev->data.op_complete == GRPC_OP_OK);
  GPR_ASSERT(on_finish_called == 0);
  grpc_event_finish(ev);
  GPR_ASSERT(on_finish_called == 1);

  shutdown_and_destroy(cc);
}
static void test_pluck(void) {
  grpc_event ev;
  grpc_completion_queue *cc;
  void *tags[128];
  grpc_cq_completion completions[GPR_ARRAY_SIZE(tags)];
  grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
  unsigned i, j;

  LOG_TEST("test_pluck");

  for (i = 0; i < GPR_ARRAY_SIZE(tags); i++) {
    tags[i] = create_test_tag();
    for (j = 0; j < i; j++) {
      GPR_ASSERT(tags[i] != tags[j]);
    }
  }

  cc = grpc_completion_queue_create(NULL);

  for (i = 0; i < GPR_ARRAY_SIZE(tags); i++) {
    grpc_cq_begin_op(cc, tags[i]);
    grpc_cq_end_op(&exec_ctx, cc, tags[i], GRPC_ERROR_NONE,
                   do_nothing_end_completion, NULL, &completions[i]);
  }

  for (i = 0; i < GPR_ARRAY_SIZE(tags); i++) {
    ev = grpc_completion_queue_pluck(cc, tags[i],
                                     gpr_inf_past(GPR_CLOCK_REALTIME), NULL);
    GPR_ASSERT(ev.tag == tags[i]);
  }

  for (i = 0; i < GPR_ARRAY_SIZE(tags); i++) {
    grpc_cq_begin_op(cc, tags[i]);
    grpc_cq_end_op(&exec_ctx, cc, tags[i], GRPC_ERROR_NONE,
                   do_nothing_end_completion, NULL, &completions[i]);
  }

  for (i = 0; i < GPR_ARRAY_SIZE(tags); i++) {
    ev = grpc_completion_queue_pluck(cc, tags[GPR_ARRAY_SIZE(tags) - i - 1],
                                     gpr_inf_past(GPR_CLOCK_REALTIME), NULL);
    GPR_ASSERT(ev.tag == tags[GPR_ARRAY_SIZE(tags) - i - 1]);
  }

  shutdown_and_destroy(cc);
  grpc_exec_ctx_finish(&exec_ctx);
}
Esempio n. 9
0
File: server.c Progetto: An-mol/grpc
static void fail_call(grpc_exec_ctx *exec_ctx, grpc_server *server,
                      requested_call *rc) {
  *rc->call = NULL;
  rc->initial_metadata->count = 0;

  server_ref(server);
  grpc_cq_end_op(exec_ctx, rc->cq_for_notification, rc->tag, 0,
                 done_request_event, rc, &rc->completion);
}
Esempio n. 10
0
void grpc_server_shutdown_and_notify(grpc_server *server,
                                     grpc_completion_queue *cq, void *tag) {
  listener *l;
  shutdown_tag *sdt;
  channel_broadcaster broadcaster;
  grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;

  GRPC_API_TRACE("grpc_server_shutdown_and_notify(server=%p, cq=%p, tag=%p)", 3,
                 (server, cq, tag));

  /* lock, and gather up some stuff to do */
  gpr_mu_lock(&server->mu_global);
  grpc_cq_begin_op(cq, tag);
  if (server->shutdown_published) {
    grpc_cq_end_op(&exec_ctx, cq, tag, GRPC_ERROR_NONE, done_published_shutdown,
                   NULL, gpr_malloc(sizeof(grpc_cq_completion)));
    gpr_mu_unlock(&server->mu_global);
    goto done;
  }
  server->shutdown_tags =
      gpr_realloc(server->shutdown_tags,
                  sizeof(shutdown_tag) * (server->num_shutdown_tags + 1));
  sdt = &server->shutdown_tags[server->num_shutdown_tags++];
  sdt->tag = tag;
  sdt->cq = cq;
  if (gpr_atm_acq_load(&server->shutdown_flag)) {
    gpr_mu_unlock(&server->mu_global);
    goto done;
  }

  server->last_shutdown_message_time = gpr_now(GPR_CLOCK_REALTIME);

  channel_broadcaster_init(server, &broadcaster);

  gpr_atm_rel_store(&server->shutdown_flag, 1);

  /* collect all unregistered then registered calls */
  gpr_mu_lock(&server->mu_call);
  kill_pending_work_locked(&exec_ctx, server,
                           GRPC_ERROR_CREATE("Server Shutdown"));
  gpr_mu_unlock(&server->mu_call);

  maybe_finish_shutdown(&exec_ctx, server);
  gpr_mu_unlock(&server->mu_global);

  /* Shutdown listeners */
  for (l = server->listeners; l; l = l->next) {
    grpc_closure_init(&l->destroy_done, listener_destroy_done, server);
    l->destroy(&exec_ctx, server, l->arg, &l->destroy_done);
  }

  channel_broadcaster_shutdown(&exec_ctx, &broadcaster, 1, 0);

done:
  grpc_exec_ctx_finish(&exec_ctx);
}
Esempio n. 11
0
static void fail_call(grpc_exec_ctx *exec_ctx, grpc_server *server,
                      size_t cq_idx, requested_call *rc, grpc_error *error) {
  *rc->call = NULL;
  rc->initial_metadata->count = 0;
  GPR_ASSERT(error != GRPC_ERROR_NONE);

  server_ref(server);
  grpc_cq_end_op(exec_ctx, server->cqs[cq_idx], rc->tag, error,
                 done_request_event, rc, &rc->completion);
}
Esempio n. 12
0
static void alarm_cb(grpc_exec_ctx *exec_ctx, void *arg, grpc_error *error) {
  grpc_alarm *alarm = (grpc_alarm *)arg;

  /* We are queuing an op on completion queue. This means, the alarm's structure
     cannot be destroyed until the op is dequeued. Adding an extra ref
     here and unref'ing when the op is dequeued will achieve this */
  GRPC_ALARM_REF(alarm, "queue-end-op");
  grpc_cq_end_op(exec_ctx, alarm->cq, alarm->tag, error, alarm_end_completion,
                 (void *)alarm, &alarm->completion);
}
Esempio n. 13
0
static void partly_done(grpc_exec_ctx *exec_ctx, state_watcher *w,
                        bool due_to_completion, grpc_error *error) {
  if (due_to_completion) {
    grpc_timer_cancel(exec_ctx, &w->alarm);
  } else {
    grpc_channel_element *client_channel_elem = grpc_channel_stack_last_element(
        grpc_channel_get_channel_stack(w->channel));
    grpc_client_channel_watch_connectivity_state(
        exec_ctx, client_channel_elem,
        grpc_polling_entity_create_from_pollset(grpc_cq_pollset(w->cq)), NULL,
        &w->on_complete, NULL);
  }

  gpr_mu_lock(&w->mu);

  if (due_to_completion) {
    if (GRPC_TRACER_ON(grpc_trace_operation_failures)) {
      GRPC_LOG_IF_ERROR("watch_completion_error", GRPC_ERROR_REF(error));
    }
    GRPC_ERROR_UNREF(error);
    error = GRPC_ERROR_NONE;
  } else {
    if (error == GRPC_ERROR_NONE) {
      error = GRPC_ERROR_CREATE_FROM_STATIC_STRING(
          "Timed out waiting for connection state change");
    } else if (error == GRPC_ERROR_CANCELLED) {
      error = GRPC_ERROR_NONE;
    }
  }
  switch (w->phase) {
    case WAITING:
      GRPC_ERROR_REF(error);
      w->error = error;
      w->phase = READY_TO_CALL_BACK;
      break;
    case READY_TO_CALL_BACK:
      if (error != GRPC_ERROR_NONE) {
        GPR_ASSERT(!due_to_completion);
        GRPC_ERROR_UNREF(w->error);
        GRPC_ERROR_REF(error);
        w->error = error;
      }
      w->phase = CALLING_BACK_AND_FINISHED;
      grpc_cq_end_op(exec_ctx, w->cq, w->tag, w->error, finished_completion, w,
                     &w->completion_storage);
      break;
    case CALLING_BACK_AND_FINISHED:
      GPR_UNREACHABLE_CODE(return );
      break;
  }
  gpr_mu_unlock(&w->mu);

  GRPC_ERROR_UNREF(error);
}
Esempio n. 14
0
static void fail_call(grpc_server *server, requested_call *rc) {
  *rc->call = NULL;
  switch (rc->type) {
    case BATCH_CALL:
      rc->data.batch.initial_metadata->count = 0;
      break;
    case REGISTERED_CALL:
      rc->data.registered.initial_metadata->count = 0;
      break;
  }
  grpc_cq_end_op(rc->cq_for_notification, rc->tag, NULL, 0);
}
Esempio n. 15
0
static void test_pluck(void) {
  grpc_event ev;
  grpc_completion_queue *cc;
  void *tags[128];
  unsigned i, j;

  LOG_TEST("test_pluck");

  for (i = 0; i < GPR_ARRAY_SIZE(tags); i++) {
    tags[i] = create_test_tag();
    for (j = 0; j < i; j++) {
      GPR_ASSERT(tags[i] != tags[j]);
    }
  }

  cc = grpc_completion_queue_create();

  for (i = 0; i < GPR_ARRAY_SIZE(tags); i++) {
    grpc_cq_begin_op(cc, NULL);
    grpc_cq_end_op(cc, tags[i], NULL, 1);
  }

  for (i = 0; i < GPR_ARRAY_SIZE(tags); i++) {
    ev = grpc_completion_queue_pluck(cc, tags[i], gpr_inf_past);
    GPR_ASSERT(ev.tag == tags[i]);
  }

  for (i = 0; i < GPR_ARRAY_SIZE(tags); i++) {
    grpc_cq_begin_op(cc, NULL);
    grpc_cq_end_op(cc, tags[i], NULL, 1);
  }

  for (i = 0; i < GPR_ARRAY_SIZE(tags); i++) {
    ev = grpc_completion_queue_pluck(cc, tags[GPR_ARRAY_SIZE(tags) - i - 1],
                                     gpr_inf_past);
    GPR_ASSERT(ev.tag == tags[GPR_ARRAY_SIZE(tags) - i - 1]);
  }

  shutdown_and_destroy(cc);
}
Esempio n. 16
0
File: server.c Progetto: An-mol/grpc
static void publish_registered_or_batch(grpc_exec_ctx *exec_ctx, void *prc,
                                        bool success) {
  requested_call *rc = prc;
  grpc_call *call = *rc->call;
  grpc_call_element *elem =
      grpc_call_stack_element(grpc_call_get_call_stack(call), 0);
  call_data *calld = elem->call_data;
  channel_data *chand = elem->channel_data;
  server_ref(chand->server);
  grpc_cq_end_op(exec_ctx, calld->cq_new, rc->tag, success, done_request_event,
                 rc, &rc->completion);
  GRPC_CALL_INTERNAL_UNREF(exec_ctx, call, "server");
}
Esempio n. 17
0
static void fail_call(grpc_exec_ctx *exec_ctx, grpc_server *server,
                      requested_call *rc) {
  *rc->call = NULL;
  switch (rc->type) {
    case BATCH_CALL:
      rc->data.batch.initial_metadata->count = 0;
      break;
    case REGISTERED_CALL:
      rc->data.registered.initial_metadata->count = 0;
      break;
  }
  server_ref(server);
  grpc_cq_end_op(exec_ctx, rc->cq_for_notification, rc->tag, 0,
                 done_request_event, rc, &rc->completion);
}
Esempio n. 18
0
static void post_batch_completion(grpc_exec_ctx *exec_ctx,
                                  batch_control *bctl) {
  grpc_call *call = bctl->call;
  if (bctl->is_notify_tag_closure) {
    grpc_exec_ctx_enqueue(exec_ctx, bctl->notify_tag, bctl->success);
    gpr_mu_lock(&call->mu);
    bctl->call->used_batches =
        (gpr_uint8)(bctl->call->used_batches &
                    ~(gpr_uint8)(1 << (bctl - bctl->call->active_batches)));
    gpr_mu_unlock(&call->mu);
    GRPC_CALL_INTERNAL_UNREF(exec_ctx, call, "completion");
  } else {
    grpc_cq_end_op(exec_ctx, bctl->call->cq, bctl->notify_tag, bctl->success,
                   finish_batch_completion, bctl, &bctl->cq_completion);
  }
}
Esempio n. 19
0
static void test_too_many_plucks(void) {
  grpc_event ev;
  grpc_completion_queue *cc;
  void *tags[GRPC_MAX_COMPLETION_QUEUE_PLUCKERS];
  grpc_cq_completion completions[GPR_ARRAY_SIZE(tags)];
  gpr_thd_id thread_ids[GPR_ARRAY_SIZE(tags)];
  struct thread_state thread_states[GPR_ARRAY_SIZE(tags)];
  gpr_thd_options thread_options = gpr_thd_options_default();
  grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
  unsigned i, j;

  LOG_TEST("test_too_many_plucks");

  cc = grpc_completion_queue_create(NULL);
  gpr_thd_options_set_joinable(&thread_options);

  for (i = 0; i < GPR_ARRAY_SIZE(tags); i++) {
    tags[i] = create_test_tag();
    for (j = 0; j < i; j++) {
      GPR_ASSERT(tags[i] != tags[j]);
    }
    thread_states[i].cc = cc;
    thread_states[i].tag = tags[i];
    gpr_thd_new(thread_ids + i, pluck_one, thread_states + i, &thread_options);
  }

  /* wait until all other threads are plucking */
  gpr_sleep_until(GRPC_TIMEOUT_MILLIS_TO_DEADLINE(1000));

  ev = grpc_completion_queue_pluck(cc, create_test_tag(),
                                   gpr_inf_future(GPR_CLOCK_REALTIME), NULL);
  GPR_ASSERT(ev.type == GRPC_QUEUE_TIMEOUT);

  for (i = 0; i < GPR_ARRAY_SIZE(tags); i++) {
    grpc_cq_begin_op(cc, tags[i]);
    grpc_cq_end_op(&exec_ctx, cc, tags[i], GRPC_ERROR_NONE,
                   do_nothing_end_completion, NULL, &completions[i]);
  }

  for (i = 0; i < GPR_ARRAY_SIZE(tags); i++) {
    gpr_thd_join(thread_ids[i]);
  }

  shutdown_and_destroy(cc);
  grpc_exec_ctx_finish(&exec_ctx);
}
Esempio n. 20
0
static void test_cq_end_op(void) {
  grpc_event ev;
  grpc_completion_queue *cc;
  void *tag = create_test_tag();

  LOG_TEST("test_cq_end_op");

  cc = grpc_completion_queue_create();

  grpc_cq_begin_op(cc, NULL);
  grpc_cq_end_op(cc, tag, NULL, 1);

  ev = grpc_completion_queue_next(cc, gpr_inf_past);
  GPR_ASSERT(ev.type == GRPC_OP_COMPLETE);
  GPR_ASSERT(ev.tag == tag);
  GPR_ASSERT(ev.success);

  shutdown_and_destroy(cc);
}
Esempio n. 21
0
static void test_cq_end_op(void) {
  grpc_event ev;
  grpc_completion_queue *cc;
  grpc_cq_completion completion;
  void *tag = create_test_tag();

  LOG_TEST("test_cq_end_op");

  cc = grpc_completion_queue_create(NULL);

  grpc_cq_begin_op(cc);
  grpc_cq_end_op(cc, tag, 1, do_nothing_end_completion, NULL, &completion);

  ev = grpc_completion_queue_next(cc, gpr_inf_past(GPR_CLOCK_REALTIME), NULL);
  GPR_ASSERT(ev.type == GRPC_OP_COMPLETE);
  GPR_ASSERT(ev.tag == tag);
  GPR_ASSERT(ev.success);

  shutdown_and_destroy(cc);
}
Esempio n. 22
0
static void publish_call(grpc_exec_ctx *exec_ctx, grpc_server *server,
                         call_data *calld, size_t cq_idx, requested_call *rc) {
  grpc_call_set_completion_queue(exec_ctx, calld->call, rc->cq_bound_to_call);
  grpc_call *call = calld->call;
  *rc->call = call;
  calld->cq_new = server->cqs[cq_idx];
  GPR_SWAP(grpc_metadata_array, *rc->initial_metadata, calld->initial_metadata);
  switch (rc->type) {
    case BATCH_CALL:
      GPR_ASSERT(calld->host != NULL);
      GPR_ASSERT(calld->path != NULL);
      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);
      rc->data.batch.details->deadline = calld->deadline;
      rc->data.batch.details->flags =
          0 | (calld->recv_idempotent_request
                   ? GRPC_INITIAL_METADATA_IDEMPOTENT_REQUEST
                   : 0);
      break;
    case REGISTERED_CALL:
      *rc->data.registered.deadline = calld->deadline;
      if (rc->data.registered.optional_payload) {
        *rc->data.registered.optional_payload = calld->payload;
      }
      break;
    default:
      GPR_UNREACHABLE_CODE(return );
  }

  grpc_call_element *elem =
      grpc_call_stack_element(grpc_call_get_call_stack(call), 0);
  channel_data *chand = elem->channel_data;
  server_ref(chand->server);
  grpc_cq_end_op(exec_ctx, calld->cq_new, rc->tag, GRPC_ERROR_NONE,
                 done_request_event, rc, &rc->completion);
}
Esempio n. 23
0
static void alarm_cb(grpc_exec_ctx *exec_ctx, void *arg, bool success) {
    grpc_alarm *alarm = arg;
    grpc_cq_end_op(exec_ctx, alarm->cq, alarm->tag, success,
                   do_nothing_end_completion, NULL, &alarm->completion);
}
Esempio n. 24
0
static void finish_batch(grpc_call *call, int success, void *tag) {
  grpc_cq_end_op(call->cq, tag, call, 1);
}
Esempio n. 25
0
static void shutdown_internal(grpc_server *server, gpr_uint8 have_shutdown_tag,
                              void *shutdown_tag) {
  listener *l;
  requested_call_array requested_calls;
  channel_data **channels;
  channel_data *c;
  size_t nchannels;
  size_t i, j;
  grpc_channel_op op;
  grpc_channel_element *elem;
  registered_method *rm;

  /* lock, and gather up some stuff to do */
  gpr_mu_lock(&server->mu);
  if (have_shutdown_tag) {
    for (i = 0; i < server->cq_count; i++) {
      grpc_cq_begin_op(server->cqs[i], NULL);
    }
    server->shutdown_tags =
        gpr_realloc(server->shutdown_tags,
                    sizeof(void *) * (server->num_shutdown_tags + 1));
    server->shutdown_tags[server->num_shutdown_tags++] = shutdown_tag;
  }
  if (server->shutdown) {
    gpr_mu_unlock(&server->mu);
    return;
  }

  nchannels = 0;
  for (c = server->root_channel_data.next; c != &server->root_channel_data;
       c = c->next) {
    nchannels++;
  }
  channels = gpr_malloc(sizeof(channel_data *) * nchannels);
  i = 0;
  for (c = server->root_channel_data.next; c != &server->root_channel_data;
       c = c->next) {
    grpc_channel_internal_ref(c->channel);
    channels[i] = c;
    i++;
  }

  /* collect all unregistered then registered calls */
  requested_calls = server->requested_calls;
  memset(&server->requested_calls, 0, sizeof(server->requested_calls));
  for (rm = server->registered_methods; rm; rm = rm->next) {
    if (requested_calls.count + rm->requested.count >
        requested_calls.capacity) {
      requested_calls.capacity =
          GPR_MAX(requested_calls.count + rm->requested.count,
                  2 * requested_calls.capacity);
      requested_calls.calls =
          gpr_realloc(requested_calls.calls, sizeof(*requested_calls.calls) *
                                                 requested_calls.capacity);
    }
    memcpy(requested_calls.calls + requested_calls.count, rm->requested.calls,
           sizeof(*requested_calls.calls) * rm->requested.count);
    requested_calls.count += rm->requested.count;
    gpr_free(rm->requested.calls);
    memset(&rm->requested, 0, sizeof(rm->requested));
  }

  server->shutdown = 1;
  if (server->lists[ALL_CALLS] == NULL) {
    for (i = 0; i < server->num_shutdown_tags; i++) {
      for (j = 0; j < server->cq_count; j++) {
        grpc_cq_end_op(server->cqs[j], server->shutdown_tags[i], NULL, 1);
      }
    }
  }
  gpr_mu_unlock(&server->mu);

  for (i = 0; i < nchannels; i++) {
    c = channels[i];
    elem = grpc_channel_stack_element(
        grpc_channel_get_channel_stack(c->channel), 0);

    op.type = GRPC_CHANNEL_GOAWAY;
    op.dir = GRPC_CALL_DOWN;
    op.data.goaway.status = GRPC_STATUS_OK;
    op.data.goaway.message = gpr_slice_from_copied_string("Server shutdown");
    elem->filter->channel_op(elem, NULL, &op);

    grpc_channel_internal_unref(c->channel);
  }
  gpr_free(channels);

  /* terminate all the requested calls */
  for (i = 0; i < requested_calls.count; i++) {
    fail_call(server, &requested_calls.calls[i]);
  }
  gpr_free(requested_calls.calls);

  /* Shutdown listeners */
  for (l = server->listeners; l; l = l->next) {
    l->destroy(server, l->arg);
  }
}
Esempio n. 26
0
grpc_call_error grpc_call_start_batch(grpc_call *call, const grpc_op *ops,
                                      size_t nops, void *tag) {
  grpc_ioreq reqs[GRPC_IOREQ_OP_COUNT];
  size_t in;
  size_t out;
  const grpc_op *op;
  grpc_ioreq *req;

  GRPC_CALL_LOG_BATCH(GPR_INFO, call, ops, nops, tag);

  if (nops == 0) {
    grpc_cq_begin_op(call->cq, call);
    grpc_cq_end_op(call->cq, tag, call, 1);
    return GRPC_CALL_OK;
  }

  /* rewrite batch ops into ioreq ops */
  for (in = 0, out = 0; in < nops; in++) {
    op = &ops[in];
    switch (op->op) {
      case GRPC_OP_SEND_INITIAL_METADATA:
        req = &reqs[out++];
        req->op = GRPC_IOREQ_SEND_INITIAL_METADATA;
        req->data.send_metadata.count = op->data.send_initial_metadata.count;
        req->data.send_metadata.metadata =
            op->data.send_initial_metadata.metadata;
        break;
      case GRPC_OP_SEND_MESSAGE:
        req = &reqs[out++];
        req->op = GRPC_IOREQ_SEND_MESSAGE;
        req->data.send_message = op->data.send_message;
        break;
      case GRPC_OP_SEND_CLOSE_FROM_CLIENT:
        if (!call->is_client) {
          return GRPC_CALL_ERROR_NOT_ON_SERVER;
        }
        req = &reqs[out++];
        req->op = GRPC_IOREQ_SEND_CLOSE;
        break;
      case GRPC_OP_SEND_STATUS_FROM_SERVER:
        if (call->is_client) {
          return GRPC_CALL_ERROR_NOT_ON_CLIENT;
        }
        req = &reqs[out++];
        req->op = GRPC_IOREQ_SEND_TRAILING_METADATA;
        req->data.send_metadata.count =
            op->data.send_status_from_server.trailing_metadata_count;
        req->data.send_metadata.metadata =
            op->data.send_status_from_server.trailing_metadata;
        req = &reqs[out++];
        req->op = GRPC_IOREQ_SEND_STATUS;
        req->data.send_status.code = op->data.send_status_from_server.status;
        req->data.send_status.details =
            op->data.send_status_from_server.status_details;
        req = &reqs[out++];
        req->op = GRPC_IOREQ_SEND_CLOSE;
        break;
      case GRPC_OP_RECV_INITIAL_METADATA:
        if (!call->is_client) {
          return GRPC_CALL_ERROR_NOT_ON_SERVER;
        }
        req = &reqs[out++];
        req->op = GRPC_IOREQ_RECV_INITIAL_METADATA;
        req->data.recv_metadata = op->data.recv_initial_metadata;
        break;
      case GRPC_OP_RECV_MESSAGE:
        req = &reqs[out++];
        req->op = GRPC_IOREQ_RECV_MESSAGE;
        req->data.recv_message = op->data.recv_message;
        break;
      case GRPC_OP_RECV_STATUS_ON_CLIENT:
        if (!call->is_client) {
          return GRPC_CALL_ERROR_NOT_ON_SERVER;
        }
        req = &reqs[out++];
        req->op = GRPC_IOREQ_RECV_STATUS;
        req->data.recv_status.set_value = set_status_value_directly;
        req->data.recv_status.user_data = op->data.recv_status_on_client.status;
        req = &reqs[out++];
        req->op = GRPC_IOREQ_RECV_STATUS_DETAILS;
        req->data.recv_status_details.details =
            op->data.recv_status_on_client.status_details;
        req->data.recv_status_details.details_capacity =
            op->data.recv_status_on_client.status_details_capacity;
        req = &reqs[out++];
        req->op = GRPC_IOREQ_RECV_TRAILING_METADATA;
        req->data.recv_metadata =
            op->data.recv_status_on_client.trailing_metadata;
        req = &reqs[out++];
        req->op = GRPC_IOREQ_RECV_CLOSE;
        break;
      case GRPC_OP_RECV_CLOSE_ON_SERVER:
        req = &reqs[out++];
        req->op = GRPC_IOREQ_RECV_STATUS;
        req->data.recv_status.set_value = set_cancelled_value;
        req->data.recv_status.user_data =
            op->data.recv_close_on_server.cancelled;
        req = &reqs[out++];
        req->op = GRPC_IOREQ_RECV_CLOSE;
        break;
    }
  }

  grpc_cq_begin_op(call->cq, call);

  return grpc_call_start_ioreq_and_call_back(call, reqs, out, finish_batch,
                                             tag);
}
Esempio n. 27
0
static void ping_done(grpc_exec_ctx *exec_ctx, void *arg, bool success) {
    ping_result *pr = arg;
    grpc_cq_end_op(exec_ctx, pr->cq, pr->tag, success, ping_destroy, pr,
                   &pr->completion_storage);
}
Esempio n. 28
0
static void ping_done(grpc_exec_ctx *exec_ctx, void *arg, grpc_error *error) {
  ping_result *pr = arg;
  grpc_cq_end_op(exec_ctx, pr->cq, pr->tag, GRPC_ERROR_REF(error), ping_destroy,
                 pr, &pr->completion_storage);
}
Esempio n. 29
0
static void alarm_cb(grpc_exec_ctx *exec_ctx, void *arg, grpc_error *error) {
  grpc_alarm *alarm = arg;
  grpc_cq_end_op(exec_ctx, alarm->cq, alarm->tag, error,
                 do_nothing_end_completion, NULL, &alarm->completion);
}