Esempio n. 1
0
/* Create a client channel:
   Asynchronously: - resolve target
                   - connect to it (trying alternatives as presented)
                   - perform handshakes */
grpc_channel *grpc_channel_create(const char *target,
                                  const grpc_channel_args *args) {
  setup *s = gpr_malloc(sizeof(setup));
  grpc_mdctx *mdctx = grpc_mdctx_create();
  grpc_channel *channel = NULL;
#define MAX_FILTERS 3
  const grpc_channel_filter *filters[MAX_FILTERS];
  int n = 0;
  filters[n++] = &grpc_client_surface_filter;
  /* TODO(census)
  if (grpc_channel_args_is_census_enabled(args)) {
    filters[n++] = &grpc_client_census_filter;
    } */
  filters[n++] = &grpc_client_channel_filter;
  GPR_ASSERT(n <= MAX_FILTERS);
  channel = grpc_channel_create_from_filters(filters, n, args, mdctx, 1);

  s->target = gpr_strdup(target);
  s->setup_callback = complete_setup;
  s->setup_user_data = grpc_channel_get_channel_stack(channel);

  grpc_client_setup_create_and_attach(grpc_channel_get_channel_stack(channel),
                                      args, mdctx, initiate_setup, done_setup,
                                      s);

  return channel;
}
Esempio n. 2
0
File: call.c Progetto: qioixiy/grpc
grpc_call *grpc_call_create(grpc_channel *channel, grpc_completion_queue *cq,
                            const void *server_transport_data) {
  size_t i;
  grpc_channel_stack *channel_stack = grpc_channel_get_channel_stack(channel);
  grpc_call *call =
      gpr_malloc(sizeof(grpc_call) + channel_stack->call_stack_size);
  memset(call, 0, sizeof(grpc_call));
  gpr_mu_init(&call->mu);
  call->channel = channel;
  call->cq = cq;
  call->is_client = server_transport_data == NULL;
  for (i = 0; i < GRPC_IOREQ_OP_COUNT; i++) {
    call->request_set[i] = REQSET_EMPTY;
  }
  if (call->is_client) {
    call->request_set[GRPC_IOREQ_SEND_TRAILING_METADATA] = REQSET_DONE;
    call->request_set[GRPC_IOREQ_SEND_STATUS] = REQSET_DONE;
  }
  grpc_channel_internal_ref(channel);
  call->metadata_context = grpc_channel_get_metadata_context(channel);
  /* one ref is dropped in response to destroy, the other in
     stream_closed */
  gpr_ref_init(&call->internal_refcount, 2);
  grpc_call_stack_init(channel_stack, server_transport_data,
                       CALL_STACK_FROM_CALL(call));
  return call;
}
Esempio n. 3
0
static grpc_channel *client_channel_factory_create_channel(
    grpc_exec_ctx *exec_ctx, grpc_client_channel_factory *cc_factory,
    const char *target, grpc_client_channel_type type,
    grpc_channel_args *args) {
  client_channel_factory *f = (client_channel_factory *)cc_factory;

  grpc_channel_args *final_args = grpc_channel_args_merge(args, f->merge_args);
  grpc_channel *channel = grpc_channel_create(exec_ctx, target, final_args,
                                              GRPC_CLIENT_CHANNEL, NULL);
  grpc_channel_args_destroy(final_args);

  grpc_resolver *resolver = grpc_resolver_create(target, &f->base);
  if (resolver != NULL) {
    grpc_client_channel_set_resolver(
        exec_ctx, grpc_channel_get_channel_stack(channel), resolver);
    GRPC_RESOLVER_UNREF(exec_ctx, resolver, "create");
  } else {
    GRPC_CHANNEL_INTERNAL_UNREF(exec_ctx, channel,
                                "client_channel_factory_create_channel");
    channel = NULL;
  }

  GRPC_SECURITY_CONNECTOR_UNREF(&f->security_connector->base,
                                "client_channel_factory_create_channel");
  return channel;
}
Esempio n. 4
0
grpc_call *grpc_call_create(grpc_channel *channel, grpc_completion_queue *cq,
                            const void *server_transport_data,
                            grpc_mdelem **add_initial_metadata,
                            size_t add_initial_metadata_count,
                            gpr_timespec send_deadline) {
  size_t i;
  grpc_transport_op initial_op;
  grpc_transport_op *initial_op_ptr = NULL;
  grpc_channel_stack *channel_stack = grpc_channel_get_channel_stack(channel);
  grpc_call *call =
      gpr_malloc(sizeof(grpc_call) + channel_stack->call_stack_size);
  memset(call, 0, sizeof(grpc_call));
  gpr_mu_init(&call->mu);
  call->channel = channel;
  call->cq = cq;
  call->is_client = server_transport_data == NULL;
  for (i = 0; i < GRPC_IOREQ_OP_COUNT; i++) {
    call->request_set[i] = REQSET_EMPTY;
  }
  if (call->is_client) {
    call->request_set[GRPC_IOREQ_SEND_TRAILING_METADATA] = REQSET_DONE;
    call->request_set[GRPC_IOREQ_SEND_STATUS] = REQSET_DONE;
  }
  GPR_ASSERT(add_initial_metadata_count < MAX_SEND_INITIAL_METADATA_COUNT);
  for (i = 0; i < add_initial_metadata_count; i++) {
    call->send_initial_metadata[i].md = add_initial_metadata[i];
  }
  call->send_initial_metadata_count = add_initial_metadata_count;
  call->send_deadline = send_deadline;
  grpc_channel_internal_ref(channel);
  call->metadata_context = grpc_channel_get_metadata_context(channel);
  grpc_sopb_init(&call->send_ops);
  grpc_sopb_init(&call->recv_ops);
  gpr_slice_buffer_init(&call->incoming_message);
  /* dropped in destroy */
  gpr_ref_init(&call->internal_refcount, 1);
  /* server hack: start reads immediately so we can get initial metadata.
     TODO(ctiller): figure out a cleaner solution */
  if (!call->is_client) {
    memset(&initial_op, 0, sizeof(initial_op));
    initial_op.recv_ops = &call->recv_ops;
    initial_op.recv_state = &call->recv_state;
    initial_op.on_done_recv = call_on_done_recv;
    initial_op.recv_user_data = call;
    initial_op.context = call->context;
    call->receiving = 1;
    GRPC_CALL_INTERNAL_REF(call, "receiving");
    initial_op_ptr = &initial_op;
  }
  grpc_call_stack_init(channel_stack, server_transport_data, initial_op_ptr,
                       CALL_STACK_FROM_CALL(call));
  if (gpr_time_cmp(send_deadline, gpr_inf_future) != 0) {
    set_deadline_alarm(call, send_deadline);
  }
  return call;
}
Esempio n. 5
0
File: server.c Progetto: penser/grpc
static void finish_shutdown_channel(void *cd, int success) {
  channel_data *chand = cd;
  grpc_channel_op op;
  op.type = GRPC_CHANNEL_DISCONNECT;
  op.dir = GRPC_CALL_DOWN;
  channel_op(grpc_channel_stack_element(
                 grpc_channel_get_channel_stack(chand->channel), 0),
             NULL, &op);
  grpc_channel_internal_unref(chand->channel);
}
Esempio n. 6
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. 7
0
void grpc_client_uchannel_set_connected_subchannel(
    grpc_channel *uchannel, grpc_connected_subchannel *connected_subchannel) {
  grpc_channel_element *elem =
      grpc_channel_stack_last_element(grpc_channel_get_channel_stack(uchannel));
  channel_data *chand = elem->channel_data;
  GPR_ASSERT(elem->filter == &grpc_client_uchannel_filter);
  gpr_mu_lock(&chand->mu_state);
  chand->connected_subchannel = connected_subchannel;
  GRPC_CONNECTED_SUBCHANNEL_REF(connected_subchannel, "uchannel");
  gpr_mu_unlock(&chand->mu_state);
}
Esempio n. 8
0
static void delete_state_watcher(grpc_exec_ctx *exec_ctx, state_watcher *w) {
  grpc_channel_element *client_channel_elem = grpc_channel_stack_last_element(
      grpc_channel_get_channel_stack(w->channel));
  if (client_channel_elem->filter == &grpc_client_channel_filter) {
    GRPC_CHANNEL_INTERNAL_UNREF(exec_ctx, w->channel,
                                "watch_channel_connectivity");
  } else {
    abort();
  }
  gpr_mu_destroy(&w->mu);
  gpr_free(w);
}
Esempio n. 9
0
static void assert_channel_connectivity(
    grpc_channel *ch, size_t num_accepted_conn_states,
    grpc_connectivity_state accepted_conn_state, ...) {
  size_t i;
  grpc_channel_stack *client_stack;
  grpc_channel_element *client_channel_filter;
  grpc_connectivity_state actual_conn_state;
  grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
  va_list ap;

  client_stack = grpc_channel_get_channel_stack(ch);
  client_channel_filter = grpc_channel_stack_last_element(client_stack);

  actual_conn_state = grpc_client_channel_check_connectivity_state(
      &exec_ctx, client_channel_filter, 0 /* don't try to connect */);
  grpc_exec_ctx_finish(&exec_ctx);
  va_start(ap, accepted_conn_state);
  for (i = 0; i < num_accepted_conn_states; i++) {
    if (actual_conn_state == accepted_conn_state) {
      break;
    }
    accepted_conn_state = va_arg(ap, grpc_connectivity_state);
  }
  va_end(ap);
  if (i == num_accepted_conn_states) {
    char **accepted_strs =
        gpr_malloc(sizeof(char *) * num_accepted_conn_states);
    char *accepted_str_joined;
    va_start(ap, accepted_conn_state);
    for (i = 0; i < num_accepted_conn_states; i++) {
      GPR_ASSERT(gpr_asprintf(&accepted_strs[i], "%d", accepted_conn_state) >
                 0);
      accepted_conn_state = va_arg(ap, grpc_connectivity_state);
    }
    va_end(ap);
    accepted_str_joined = gpr_strjoin_sep((const char **)accepted_strs,
                                          num_accepted_conn_states, ", ", NULL);
    gpr_log(
        GPR_ERROR,
        "Channel connectivity assertion failed: expected <one of [%s]>, got %d",
        accepted_str_joined, actual_conn_state);

    for (i = 0; i < num_accepted_conn_states; i++) {
      gpr_free(accepted_strs[i]);
    }
    gpr_free(accepted_strs);
    gpr_free(accepted_str_joined);
    abort();
  }
}
Esempio n. 10
0
void grpc_channel_watch_connectivity_state(
    grpc_channel *channel, grpc_connectivity_state last_observed_state,
    gpr_timespec deadline, grpc_completion_queue *cq, void *tag) {
  grpc_channel_element *client_channel_elem =
      grpc_channel_stack_last_element(grpc_channel_get_channel_stack(channel));
  grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
  state_watcher *w = (state_watcher *)gpr_malloc(sizeof(*w));

  GRPC_API_TRACE(
      "grpc_channel_watch_connectivity_state("
      "channel=%p, last_observed_state=%d, "
      "deadline=gpr_timespec { tv_sec: %" PRId64
      ", tv_nsec: %d, clock_type: %d }, "
      "cq=%p, tag=%p)",
      7, (channel, (int)last_observed_state, deadline.tv_sec, deadline.tv_nsec,
          (int)deadline.clock_type, cq, tag));

  GPR_ASSERT(grpc_cq_begin_op(cq, tag));

  gpr_mu_init(&w->mu);
  GRPC_CLOSURE_INIT(&w->on_complete, watch_complete, w,
                    grpc_schedule_on_exec_ctx);
  GRPC_CLOSURE_INIT(&w->on_timeout, timeout_complete, w,
                    grpc_schedule_on_exec_ctx);
  w->phase = WAITING;
  w->state = last_observed_state;
  w->cq = cq;
  w->tag = tag;
  w->channel = channel;
  w->error = NULL;

  watcher_timer_init_arg *wa =
      (watcher_timer_init_arg *)gpr_malloc(sizeof(watcher_timer_init_arg));
  wa->w = w;
  wa->deadline = deadline;
  GRPC_CLOSURE_INIT(&w->watcher_timer_init, watcher_timer_init, wa,
                    grpc_schedule_on_exec_ctx);

  if (client_channel_elem->filter == &grpc_client_channel_filter) {
    GRPC_CHANNEL_INTERNAL_REF(channel, "watch_channel_connectivity");
    grpc_client_channel_watch_connectivity_state(
        &exec_ctx, client_channel_elem,
        grpc_polling_entity_create_from_pollset(grpc_cq_pollset(cq)), &w->state,
        &w->on_complete, &w->watcher_timer_init);
  } else {
    abort();
  }

  grpc_exec_ctx_finish(&exec_ctx);
}
static void client_setup_transport(void *ts, grpc_transport *transport,
                                   grpc_mdctx *mdctx) {
  sp_client_setup *cs = ts;

  const grpc_channel_filter *filters[] = {&grpc_http_client_filter,
                                          &grpc_connected_channel_filter};
  size_t nfilters = sizeof(filters) / sizeof(*filters);
  grpc_channel *channel = grpc_channel_create_from_filters(
      filters, nfilters, cs->client_args, mdctx, 1);

  cs->f->client = channel;

  grpc_connected_channel_bind_transport(grpc_channel_get_channel_stack(channel),
                                        transport);
}
Esempio n. 12
0
static void finish_shutdown_channel(void *p, int success) {
  shutdown_channel_args *sca = p;
  grpc_channel_op op;

  if (sca->send_goaway) {
    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");
    channel_op(grpc_channel_stack_element(
                   grpc_channel_get_channel_stack(sca->chand->channel), 0),
               NULL, &op);
  }
  if (sca->send_disconnect) {
    op.type = GRPC_CHANNEL_DISCONNECT;
    op.dir = GRPC_CALL_DOWN;
    channel_op(grpc_channel_stack_element(
                   grpc_channel_get_channel_stack(sca->chand->channel), 0),
               NULL, &op);
  }
  GRPC_CHANNEL_INTERNAL_UNREF(sca->chand->channel, "shutdown");

  gpr_free(sca);
}
Esempio n. 13
0
static void client_setup_transport(grpc_exec_ctx *exec_ctx, void *ts,
                                   grpc_transport *transport) {
  sp_client_setup *cs = ts;

  const grpc_channel_filter *filters[] = {&grpc_http_client_filter,
                                          &grpc_compress_filter,
                                          &grpc_connected_channel_filter};
  size_t nfilters = sizeof(filters) / sizeof(*filters);
  grpc_channel *channel = grpc_channel_create_from_filters(
      exec_ctx, "socketpair-target", filters, nfilters, cs->client_args, 1);

  cs->f->client = channel;

  grpc_connected_channel_bind_transport(grpc_channel_get_channel_stack(channel),
                                        transport);
}
Esempio n. 14
0
/* Create a client channel:
   Asynchronously: - resolve target
                   - connect to it (trying alternatives as presented)
                   - perform handshakes */
grpc_channel *grpc_insecure_channel_create(const char *target,
                                           const grpc_channel_args *args,
                                           void *reserved) {
  grpc_channel *channel = NULL;
#define MAX_FILTERS 3
  const grpc_channel_filter *filters[MAX_FILTERS];
  grpc_resolver *resolver;
  subchannel_factory *f;
  grpc_mdctx *mdctx = grpc_mdctx_create();
  grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
  size_t n = 0;
  GRPC_API_TRACE(
      "grpc_insecure_channel_create(target=%p, args=%p, reserved=%p)", 3,
      (target, args, reserved));
  GPR_ASSERT(!reserved);
  if (grpc_channel_args_is_census_enabled(args)) {
    filters[n++] = &grpc_client_census_filter;
  }
  filters[n++] = &grpc_compress_filter;
  filters[n++] = &grpc_client_channel_filter;
  GPR_ASSERT(n <= MAX_FILTERS);

  channel = grpc_channel_create_from_filters(&exec_ctx, target, filters, n,
                                             args, mdctx, 1);

  f = gpr_malloc(sizeof(*f));
  f->base.vtable = &subchannel_factory_vtable;
  gpr_ref_init(&f->refs, 1);
  grpc_mdctx_ref(mdctx);
  f->mdctx = mdctx;
  f->merge_args = grpc_channel_args_copy(args);
  f->master = channel;
  GRPC_CHANNEL_INTERNAL_REF(f->master, "subchannel_factory");
  resolver = grpc_resolver_create(target, &f->base);
  if (!resolver) {
    return NULL;
  }

  grpc_client_channel_set_resolver(
      &exec_ctx, grpc_channel_get_channel_stack(channel), resolver);
  GRPC_RESOLVER_UNREF(&exec_ctx, resolver, "create");
  grpc_subchannel_factory_unref(&exec_ctx, &f->base);

  grpc_exec_ctx_finish(&exec_ctx);

  return channel;
}
Esempio n. 15
0
void grpc_channel_ping(grpc_channel *channel, grpc_completion_queue *cq,
                       void *tag, void *reserved) {
    grpc_transport_op op;
    ping_result *pr = gpr_malloc(sizeof(*pr));
    grpc_channel_element *top_elem =
        grpc_channel_stack_element(grpc_channel_get_channel_stack(channel), 0);
    grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
    GPR_ASSERT(reserved == NULL);
    memset(&op, 0, sizeof(op));
    pr->tag = tag;
    pr->cq = cq;
    grpc_closure_init(&pr->closure, ping_done, pr);
    op.send_ping = &pr->closure;
    op.bind_pollset = grpc_cq_pollset(cq);
    grpc_cq_begin_op(cq, tag);
    top_elem->filter->start_transport_op(&exec_ctx, top_elem, &op);
    grpc_exec_ctx_finish(&exec_ctx);
}
Esempio n. 16
0
static void destroy_channel(grpc_exec_ctx *exec_ctx, channel_data *chand) {
  if (is_channel_orphaned(chand)) return;
  GPR_ASSERT(chand->server != NULL);
  orphan_channel(chand);
  server_ref(chand->server);
  maybe_finish_shutdown(exec_ctx, chand->server);
  chand->finish_destroy_channel_closure.cb = finish_destroy_channel;
  chand->finish_destroy_channel_closure.cb_arg = chand;

  grpc_transport_op op;
  memset(&op, 0, sizeof(op));
  op.set_accept_stream = true;
  op.on_consumed = &chand->finish_destroy_channel_closure;
  grpc_channel_next_op(exec_ctx,
                       grpc_channel_stack_element(
                           grpc_channel_get_channel_stack(chand->channel), 0),
                       &op);
}
Esempio n. 17
0
void grpc_channel_ping(grpc_channel *channel, grpc_completion_queue *cq,
                       void *tag, void *reserved) {
  GRPC_API_TRACE("grpc_channel_ping(channel=%p, cq=%p, tag=%p, reserved=%p)", 4,
                 (channel, cq, tag, reserved));
  grpc_transport_op *op = grpc_make_transport_op(NULL);
  ping_result *pr = gpr_malloc(sizeof(*pr));
  grpc_channel_element *top_elem =
      grpc_channel_stack_element(grpc_channel_get_channel_stack(channel), 0);
  grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
  GPR_ASSERT(reserved == NULL);
  pr->tag = tag;
  pr->cq = cq;
  grpc_closure_init(&pr->closure, ping_done, pr);
  op->send_ping = &pr->closure;
  op->bind_pollset = grpc_cq_pollset(cq);
  grpc_cq_begin_op(cq, tag);
  top_elem->filter->start_transport_op(&exec_ctx, top_elem, op);
  grpc_exec_ctx_finish(&exec_ctx);
}
Esempio n. 18
0
static void send_shutdown(grpc_exec_ctx *exec_ctx, grpc_channel *channel,
                          int send_goaway, grpc_error *send_disconnect) {
  grpc_transport_op op;
  struct shutdown_cleanup_args *sc;
  grpc_channel_element *elem;

  memset(&op, 0, sizeof(op));
  op.send_goaway = send_goaway;
  sc = gpr_malloc(sizeof(*sc));
  sc->slice = gpr_slice_from_copied_string("Server shutdown");
  op.goaway_message = &sc->slice;
  op.goaway_status = GRPC_STATUS_OK;
  op.disconnect_with_error = send_disconnect;
  grpc_closure_init(&sc->closure, shutdown_cleanup, sc);
  op.on_consumed = &sc->closure;

  elem = grpc_channel_stack_element(grpc_channel_get_channel_stack(channel), 0);
  elem->filter->start_transport_op(exec_ctx, elem, &op);
}
Esempio n. 19
0
static grpc_channel *client_channel_factory_create_channel(
    grpc_exec_ctx *exec_ctx, grpc_client_channel_factory *cc_factory,
    const char *target, grpc_client_channel_type type,
    const grpc_channel_args *args) {
    client_channel_factory *f = (client_channel_factory *)cc_factory;
    grpc_channel *channel =
        grpc_channel_create(exec_ctx, target, args, GRPC_CLIENT_CHANNEL, NULL);
    grpc_resolver *resolver = grpc_resolver_create(target, args);
    if (resolver != NULL) {
        grpc_client_channel_finish_initialization(
            exec_ctx, grpc_channel_get_channel_stack(channel), resolver, &f->base);
        GRPC_RESOLVER_UNREF(exec_ctx, resolver, "create");
    } else {
        GRPC_CHANNEL_INTERNAL_UNREF(exec_ctx, channel,
                                    "client_channel_factory_create_channel");
        channel = NULL;
    }
    return channel;
}
Esempio n. 20
0
static void channel_connectivity_changed(grpc_exec_ctx *exec_ctx, void *cd,
                                         grpc_error *error) {
  channel_data *chand = cd;
  grpc_server *server = chand->server;
  if (chand->connectivity_state != GRPC_CHANNEL_SHUTDOWN) {
    grpc_transport_op op;
    memset(&op, 0, sizeof(op));
    op.on_connectivity_state_change = &chand->channel_connectivity_changed,
    op.connectivity_state = &chand->connectivity_state;
    grpc_channel_next_op(exec_ctx,
                         grpc_channel_stack_element(
                             grpc_channel_get_channel_stack(chand->channel), 0),
                         &op);
  } else {
    gpr_mu_lock(&server->mu_global);
    destroy_channel(exec_ctx, chand);
    gpr_mu_unlock(&server->mu_global);
    GRPC_CHANNEL_INTERNAL_UNREF(exec_ctx, chand->channel, "connectivity");
  }
}
Esempio n. 21
0
grpc_channel *grpc_lame_client_channel_create(const char *target,
                                              grpc_status_code error_code,
                                              const char *error_message) {
  grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
  grpc_channel_element *elem;
  channel_data *chand;
  grpc_channel *channel = grpc_channel_create(&exec_ctx, target, NULL,
                                              GRPC_CLIENT_LAME_CHANNEL, NULL);
  elem = grpc_channel_stack_element(grpc_channel_get_channel_stack(channel), 0);
  GRPC_API_TRACE(
      "grpc_lame_client_channel_create(target=%s, error_code=%d, "
      "error_message=%s)",
      3, (target, (int)error_code, error_message));
  GPR_ASSERT(elem->filter == &grpc_lame_filter);
  chand = (channel_data *)elem->channel_data;
  chand->error_code = error_code;
  chand->error_message = error_message;
  grpc_exec_ctx_finish(&exec_ctx);
  return channel;
}
Esempio n. 22
0
/* The evil twin of grpc_insecure_channel_create. It allows the test to use the
 * custom-built sniffing subchannel_factory */
grpc_channel *channel_create(const char *target, const grpc_channel_args *args,
                             grpc_subchannel **sniffed_subchannel) {
  grpc_channel *channel = NULL;
#define MAX_FILTERS 1
  const grpc_channel_filter *filters[MAX_FILTERS];
  grpc_resolver *resolver;
  subchannel_factory *f;
  grpc_mdctx *mdctx = grpc_mdctx_create();
  grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
  size_t n = 0;

  filters[n++] = &grpc_client_channel_filter;
  GPR_ASSERT(n <= MAX_FILTERS);

  channel = grpc_channel_create_from_filters(&exec_ctx, target, filters, n,
                                             args, mdctx, 1);

  f = gpr_malloc(sizeof(*f));
  f->sniffed_subchannel = sniffed_subchannel;
  f->base.vtable = &test_subchannel_factory_vtable;
  gpr_ref_init(&f->refs, 1);
  grpc_mdctx_ref(mdctx);
  f->mdctx = mdctx;
  f->merge_args = grpc_channel_args_copy(args);
  f->master = channel;
  GRPC_CHANNEL_INTERNAL_REF(f->master, "test_subchannel_factory");
  resolver = grpc_resolver_create(target, &f->base);
  if (!resolver) {
    return NULL;
  }

  grpc_client_channel_set_resolver(
      &exec_ctx, grpc_channel_get_channel_stack(channel), resolver);
  GRPC_RESOLVER_UNREF(&exec_ctx, resolver, "test_create");
  grpc_subchannel_factory_unref(&exec_ctx, &f->base);

  grpc_exec_ctx_finish(&exec_ctx);

  return channel;
}
Esempio n. 23
0
void test_transport_op(grpc_channel *channel) {
  grpc_transport_op *op;
  grpc_channel_element *elem;
  grpc_connectivity_state state = GRPC_CHANNEL_IDLE;
  grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;

  grpc_closure_init(&transport_op_cb, verify_connectivity, &state,
                    grpc_schedule_on_exec_ctx);

  op = grpc_make_transport_op(NULL);
  op->on_connectivity_state_change = &transport_op_cb;
  op->connectivity_state = &state;
  elem = grpc_channel_stack_element(grpc_channel_get_channel_stack(channel), 0);
  elem->filter->start_transport_op(&exec_ctx, elem, op);
  grpc_exec_ctx_finish(&exec_ctx);

  grpc_closure_init(&transport_op_cb, do_nothing, NULL,
                    grpc_schedule_on_exec_ctx);
  op = grpc_make_transport_op(&transport_op_cb);
  elem->filter->start_transport_op(&exec_ctx, elem, op);
  grpc_exec_ctx_finish(&exec_ctx);
}
Esempio n. 24
0
grpc_channel *grpc_lame_client_channel_create(const char *target,
                                              grpc_status_code error_code,
                                              const char *error_message) {
  grpc_channel *channel;
  grpc_channel_element *elem;
  channel_data *chand;
  grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
  static const grpc_channel_filter *filters[] = {&lame_filter};
  channel = grpc_channel_create_from_filters(&exec_ctx, target, filters, 1,
                                             NULL, grpc_mdctx_create(), 1);
  elem = grpc_channel_stack_element(grpc_channel_get_channel_stack(channel), 0);
  GRPC_API_TRACE(
      "grpc_lame_client_channel_create(target=%s, error_code=%d, "
      "error_message=%s)",
      3, (target, (int)error_code, error_message));
  GPR_ASSERT(elem->filter == &lame_filter);
  chand = (channel_data *)elem->channel_data;
  chand->error_code = error_code;
  chand->error_message = error_message;
  grpc_exec_ctx_finish(&exec_ctx);
  return channel;
}
Esempio n. 25
0
static grpc_channel *client_channel_factory_create_channel(
    grpc_exec_ctx *exec_ctx, grpc_client_channel_factory *cc_factory,
    const char *target, grpc_client_channel_type type,
    grpc_channel_args *args) {
  client_channel_factory *f = (client_channel_factory *)cc_factory;
  grpc_channel_args *final_args = grpc_channel_args_merge(args, f->merge_args);
  grpc_channel *channel = grpc_channel_create(exec_ctx, target, final_args,
                                              GRPC_CLIENT_CHANNEL, NULL);
  grpc_channel_args_destroy(final_args);
  grpc_resolver *resolver = grpc_resolver_create(target);
  if (!resolver) {
    GRPC_CHANNEL_INTERNAL_UNREF(exec_ctx, channel,
                                "client_channel_factory_create_channel");
    return NULL;
  }

  grpc_client_channel_finish_initialization(
      exec_ctx, grpc_channel_get_channel_stack(channel), resolver, &f->base);
  GRPC_RESOLVER_UNREF(exec_ctx, resolver, "create_channel");

  return channel;
}
Esempio n. 26
0
/* Create a client channel:
   Asynchronously: - resolve target
                   - connect to it (trying alternatives as presented)
                   - perform handshakes */
grpc_channel *grpc_insecure_channel_create(const char *target,
                                           const grpc_channel_args *args,
                                           void *reserved) {
  grpc_channel *channel = NULL;
  grpc_resolver *resolver;
  subchannel_factory *f;
  grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
  GRPC_API_TRACE(
      "grpc_insecure_channel_create(target=%p, args=%p, reserved=%p)", 3,
      (target, args, reserved));
  GPR_ASSERT(!reserved);

  channel =
      grpc_channel_create(&exec_ctx, target, args, GRPC_CLIENT_CHANNEL, NULL);

  f = gpr_malloc(sizeof(*f));
  f->base.vtable = &subchannel_factory_vtable;
  gpr_ref_init(&f->refs, 1);
  f->merge_args = grpc_channel_args_copy(args);
  f->master = channel;
  GRPC_CHANNEL_INTERNAL_REF(f->master, "subchannel_factory");
  resolver = grpc_resolver_create(target, &f->base);
  if (!resolver) {
    GRPC_CHANNEL_INTERNAL_UNREF(&exec_ctx, f->master, "subchannel_factory");
    grpc_subchannel_factory_unref(&exec_ctx, &f->base);
    grpc_exec_ctx_finish(&exec_ctx);
    return NULL;
  }

  grpc_client_channel_set_resolver(
      &exec_ctx, grpc_channel_get_channel_stack(channel), resolver);
  GRPC_RESOLVER_UNREF(&exec_ctx, resolver, "create");
  grpc_subchannel_factory_unref(&exec_ctx, &f->base);

  grpc_exec_ctx_finish(&exec_ctx);

  return channel;
}
Esempio n. 27
0
grpc_connectivity_state grpc_channel_check_connectivity_state(
    grpc_channel *channel, int try_to_connect) {
  /* forward through to the underlying client channel */
  grpc_channel_element *client_channel_elem =
      grpc_channel_stack_last_element(grpc_channel_get_channel_stack(channel));
  grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
  grpc_connectivity_state state;
  GRPC_API_TRACE(
      "grpc_channel_check_connectivity_state(channel=%p, try_to_connect=%d)", 2,
      (channel, try_to_connect));
  if (client_channel_elem->filter == &grpc_client_channel_filter) {
    state = grpc_client_channel_check_connectivity_state(
        &exec_ctx, client_channel_elem, try_to_connect);
    grpc_exec_ctx_finish(&exec_ctx);
    return state;
  }
  gpr_log(GPR_ERROR,
          "grpc_channel_check_connectivity_state called on something that is "
          "not a client channel, but '%s'",
          client_channel_elem->filter->name);
  grpc_exec_ctx_finish(&exec_ctx);
  return GRPC_CHANNEL_SHUTDOWN;
}
Esempio n. 28
0
grpc_call *grpc_call_create(grpc_channel *channel, grpc_call *parent_call,
                            uint32_t propagation_mask,
                            grpc_completion_queue *cq,
                            const void *server_transport_data,
                            grpc_mdelem **add_initial_metadata,
                            size_t add_initial_metadata_count,
                            gpr_timespec send_deadline) {
  size_t i, j;
  grpc_channel_stack *channel_stack = grpc_channel_get_channel_stack(channel);
  grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
  grpc_call *call;
  GPR_TIMER_BEGIN("grpc_call_create", 0);
  call = gpr_malloc(sizeof(grpc_call) + channel_stack->call_stack_size);
  memset(call, 0, sizeof(grpc_call));
  gpr_mu_init(&call->mu);
  call->channel = channel;
  call->cq = cq;
  call->parent = parent_call;
  call->is_client = server_transport_data == NULL;
  if (call->is_client) {
    GPR_ASSERT(add_initial_metadata_count < MAX_SEND_EXTRA_METADATA_COUNT);
    for (i = 0; i < add_initial_metadata_count; i++) {
      call->send_extra_metadata[i].md = add_initial_metadata[i];
    }
    call->send_extra_metadata_count = (int)add_initial_metadata_count;
  } else {
    GPR_ASSERT(add_initial_metadata_count == 0);
    call->send_extra_metadata_count = 0;
  }
  for (i = 0; i < 2; i++) {
    for (j = 0; j < 2; j++) {
      call->metadata_batch[i][j].deadline = gpr_inf_future(GPR_CLOCK_MONOTONIC);
    }
  }
  call->send_deadline = send_deadline;
  GRPC_CHANNEL_INTERNAL_REF(channel, "call");
  /* initial refcount dropped by grpc_call_destroy */
  grpc_call_stack_init(&exec_ctx, channel_stack, 1, destroy_call, call,
                       call->context, server_transport_data,
                       CALL_STACK_FROM_CALL(call));
  if (cq != NULL) {
    GRPC_CQ_INTERNAL_REF(cq, "bind");
    grpc_call_stack_set_pollset(&exec_ctx, CALL_STACK_FROM_CALL(call),
                                grpc_cq_pollset(cq));
  }
  if (parent_call != NULL) {
    GRPC_CALL_INTERNAL_REF(parent_call, "child");
    GPR_ASSERT(call->is_client);
    GPR_ASSERT(!parent_call->is_client);

    gpr_mu_lock(&parent_call->mu);

    if (propagation_mask & GRPC_PROPAGATE_DEADLINE) {
      send_deadline = gpr_time_min(
          gpr_convert_clock_type(send_deadline,
                                 parent_call->send_deadline.clock_type),
          parent_call->send_deadline);
    }
    /* for now GRPC_PROPAGATE_TRACING_CONTEXT *MUST* be passed with
     * GRPC_PROPAGATE_STATS_CONTEXT */
    /* TODO(ctiller): This should change to use the appropriate census start_op
     * call. */
    if (propagation_mask & GRPC_PROPAGATE_CENSUS_TRACING_CONTEXT) {
      GPR_ASSERT(propagation_mask & GRPC_PROPAGATE_CENSUS_STATS_CONTEXT);
      grpc_call_context_set(call, GRPC_CONTEXT_TRACING,
                            parent_call->context[GRPC_CONTEXT_TRACING].value,
                            NULL);
    } else {
      GPR_ASSERT(propagation_mask & GRPC_PROPAGATE_CENSUS_STATS_CONTEXT);
    }
    if (propagation_mask & GRPC_PROPAGATE_CANCELLATION) {
      call->cancellation_is_inherited = 1;
    }

    if (parent_call->first_child == NULL) {
      parent_call->first_child = call;
      call->sibling_next = call->sibling_prev = call;
    } else {
      call->sibling_next = parent_call->first_child;
      call->sibling_prev = parent_call->first_child->sibling_prev;
      call->sibling_next->sibling_prev = call->sibling_prev->sibling_next =
          call;
    }

    gpr_mu_unlock(&parent_call->mu);
  }
  if (gpr_time_cmp(send_deadline, gpr_inf_future(send_deadline.clock_type)) !=
      0) {
    set_deadline_alarm(&exec_ctx, call, send_deadline);
  }
  grpc_exec_ctx_finish(&exec_ctx);
  GPR_TIMER_END("grpc_call_create", 0);
  return call;
}
Esempio n. 29
0
File: server.c Progetto: penser/grpc
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, GRPC_SERVER_SHUTDOWN);
    }
    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_server_shutdown(server->cqs[j], server->shutdown_tags[i]);
      }
    }
  }
  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. 30
0
File: server.c Progetto: penser/grpc
grpc_transport_setup_result grpc_server_setup_transport(
    grpc_server *s, grpc_transport *transport,
    grpc_channel_filter const **extra_filters, size_t num_extra_filters,
    grpc_mdctx *mdctx) {
  size_t num_filters = s->channel_filter_count + num_extra_filters + 1;
  grpc_channel_filter const **filters =
      gpr_malloc(sizeof(grpc_channel_filter *) * num_filters);
  size_t i;
  size_t num_registered_methods;
  size_t alloc;
  registered_method *rm;
  channel_registered_method *crm;
  grpc_channel *channel;
  channel_data *chand;
  grpc_mdstr *host;
  grpc_mdstr *method;
  gpr_uint32 hash;
  gpr_uint32 slots;
  gpr_uint32 probes;
  gpr_uint32 max_probes = 0;
  grpc_transport_setup_result result;

  for (i = 0; i < s->channel_filter_count; i++) {
    filters[i] = s->channel_filters[i];
  }
  for (; i < s->channel_filter_count + num_extra_filters; i++) {
    filters[i] = extra_filters[i - s->channel_filter_count];
  }
  filters[i] = &grpc_connected_channel_filter;

  for (i = 0; i < s->cq_count; i++) {
    grpc_transport_add_to_pollset(transport, grpc_cq_pollset(s->cqs[i]));
  }

  channel = grpc_channel_create_from_filters(filters, num_filters,
                                             s->channel_args, mdctx, 0);
  chand = (channel_data *)grpc_channel_stack_element(
              grpc_channel_get_channel_stack(channel), 0)
              ->channel_data;
  chand->server = s;
  server_ref(s);
  chand->channel = channel;

  num_registered_methods = 0;
  for (rm = s->registered_methods; rm; rm = rm->next) {
    num_registered_methods++;
  }
  /* build a lookup table phrased in terms of mdstr's in this channels context
     to quickly find registered methods */
  if (num_registered_methods > 0) {
    slots = 2 * num_registered_methods;
    alloc = sizeof(channel_registered_method) * slots;
    chand->registered_methods = gpr_malloc(alloc);
    memset(chand->registered_methods, 0, alloc);
    for (rm = s->registered_methods; rm; rm = rm->next) {
      host = rm->host ? grpc_mdstr_from_string(mdctx, rm->host) : NULL;
      method = grpc_mdstr_from_string(mdctx, rm->method);
      hash = GRPC_MDSTR_KV_HASH(host ? host->hash : 0, method->hash);
      for (probes = 0; chand->registered_methods[(hash + probes) % slots]
                           .server_registered_method != NULL;
           probes++)
        ;
      if (probes > max_probes) max_probes = probes;
      crm = &chand->registered_methods[(hash + probes) % slots];
      crm->server_registered_method = rm;
      crm->host = host;
      crm->method = method;
    }
    chand->registered_method_slots = slots;
    chand->registered_method_max_probes = max_probes;
  }

  result = grpc_connected_channel_bind_transport(
      grpc_channel_get_channel_stack(channel), transport);

  gpr_mu_lock(&s->mu);
  chand->next = &s->root_channel_data;
  chand->prev = chand->next->prev;
  chand->next->prev = chand->prev->next = chand;
  gpr_mu_unlock(&s->mu);

  gpr_free(filters);

  return result;
}