Beispiel #1
0
static void destroy_call(grpc_exec_ctx *exec_ctx, void *call, int success) {
  size_t i;
  int ii;
  grpc_call *c = call;
  GPR_TIMER_BEGIN("destroy_call", 0);
  for (i = 0; i < 2; i++) {
    grpc_metadata_batch_destroy(
        &c->metadata_batch[1 /* is_receiving */][i /* is_initial */]);
  }
  if (c->receiving_stream != NULL) {
    grpc_byte_stream_destroy(c->receiving_stream);
  }
  grpc_call_stack_destroy(exec_ctx, CALL_STACK_FROM_CALL(c));
  GRPC_CHANNEL_INTERNAL_UNREF(exec_ctx, c->channel, "call");
  gpr_mu_destroy(&c->mu);
  for (i = 0; i < STATUS_SOURCE_COUNT; i++) {
    if (c->status[i].details) {
      GRPC_MDSTR_UNREF(c->status[i].details);
    }
  }
  for (ii = 0; ii < c->send_extra_metadata_count; ii++) {
    GRPC_MDELEM_UNREF(c->send_extra_metadata[ii].md);
  }
  for (i = 0; i < GRPC_CONTEXT_COUNT; i++) {
    if (c->context[i].destroy) {
      c->context[i].destroy(c->context[i].value);
    }
  }
  if (c->cq) {
    GRPC_CQ_INTERNAL_UNREF(c->cq, "bind");
  }
  gpr_free(c);
  GPR_TIMER_END("destroy_call", 0);
}
Beispiel #2
0
void grpc_channel_internal_unref(grpc_exec_ctx *exec_ctx, grpc_channel *channel,
                                 const char *reason) {
  gpr_log(GPR_DEBUG, "CHANNEL: unref %p %d -> %d [%s]", channel,
          channel->refs.count, channel->refs.count - 1, reason);
#else
void grpc_channel_internal_unref(grpc_exec_ctx *exec_ctx,
                                 grpc_channel *channel) {
#endif
  if (gpr_unref(&channel->refs)) {
    destroy_channel(exec_ctx, channel);
  }
}

void grpc_channel_destroy(grpc_channel *channel) {
  grpc_transport_op op;
  grpc_channel_element *elem;
  grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
  GRPC_API_TRACE("grpc_channel_destroy(channel=%p)", 1, (channel));
  memset(&op, 0, sizeof(op));
  op.disconnect = 1;
  elem = grpc_channel_stack_element(CHANNEL_STACK_FROM_CHANNEL(channel), 0);
  elem->filter->start_transport_op(&exec_ctx, elem, &op);

  GRPC_CHANNEL_INTERNAL_UNREF(&exec_ctx, channel, "channel");

  grpc_exec_ctx_finish(&exec_ctx);
}
Beispiel #3
0
static void finish_destroy_channel(grpc_exec_ctx *exec_ctx, void *cd,
                                   grpc_error *error) {
  channel_data *chand = cd;
  grpc_server *server = chand->server;
  GRPC_CHANNEL_INTERNAL_UNREF(exec_ctx, chand->channel, "server");
  server_unref(exec_ctx, server);
}
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;
}
Beispiel #5
0
static void finish_destroy_channel(grpc_exec_ctx *exec_ctx, void *cd,
                                   int success) {
  channel_data *chand = cd;
  grpc_server *server = chand->server;
  gpr_log(GPR_DEBUG, "finish_destroy_channel: %p", chand->channel);
  GRPC_CHANNEL_INTERNAL_UNREF(exec_ctx, chand->channel, "server");
  server_unref(exec_ctx, server);
}
Beispiel #6
0
static void subchannel_factory_unref(grpc_exec_ctx *exec_ctx,
                                     grpc_subchannel_factory *scf) {
  subchannel_factory *f = (subchannel_factory *)scf;
  if (gpr_unref(&f->refs)) {
    GRPC_CHANNEL_INTERNAL_UNREF(exec_ctx, f->master, "subchannel_factory");
    grpc_channel_args_destroy(f->merge_args);
    gpr_free(f);
  }
}
Beispiel #7
0
static void subchannel_factory_unref(grpc_exec_ctx *exec_ctx,
                                     grpc_subchannel_factory *scf) {
  subchannel_factory *f = (subchannel_factory *)scf;
  if (gpr_unref(&f->refs)) {
    GRPC_SECURITY_CONNECTOR_UNREF(&f->security_connector->base,
                                  "subchannel_factory");
    GRPC_CHANNEL_INTERNAL_UNREF(exec_ctx, f->master, "subchannel_factory");
    grpc_channel_args_destroy(f->merge_args);
    gpr_free(f);
  }
}
Beispiel #8
0
static void channel_broadcaster_shutdown(grpc_exec_ctx *exec_ctx,
                                         channel_broadcaster *cb,
                                         int send_goaway,
                                         int force_disconnect) {
  size_t i;

  for (i = 0; i < cb->num_channels; i++) {
    send_shutdown(exec_ctx, cb->channels[i], send_goaway, force_disconnect);
    GRPC_CHANNEL_INTERNAL_UNREF(exec_ctx, cb->channels[i], "broadcast");
  }
  gpr_free(cb->channels);
}
Beispiel #9
0
static void client_channel_factory_unref(
    grpc_exec_ctx *exec_ctx, grpc_client_channel_factory *cc_factory) {
  client_channel_factory *f = (client_channel_factory *)cc_factory;
  if (gpr_unref(&f->refs)) {
    if (f->master != NULL) {
      GRPC_CHANNEL_INTERNAL_UNREF(exec_ctx, f->master,
                                  "client_channel_factory");
    }
    grpc_channel_args_destroy(f->merge_args);
    gpr_free(f);
  }
}
Beispiel #10
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);
}
Beispiel #11
0
static void client_channel_factory_unref(
    grpc_exec_ctx *exec_ctx, grpc_client_channel_factory *cc_factory) {
  client_channel_factory *f = (client_channel_factory *)cc_factory;
  if (gpr_unref(&f->refs)) {
    GRPC_SECURITY_CONNECTOR_UNREF(&f->security_connector->base,
                                  "client_channel_factory");
    if (f->master != NULL) {
      GRPC_CHANNEL_INTERNAL_UNREF(exec_ctx, f->master,
                                  "client_channel_factory");
    }
    grpc_channel_args_destroy(f->merge_args);
    gpr_free(f);
  }
}
Beispiel #12
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_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, 1);

    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;
}
Beispiel #13
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;
}
Beispiel #14
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");
  }
}
Beispiel #15
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;
}
Beispiel #16
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;
}
Beispiel #17
0
void grpc_channel_internal_unref(grpc_channel *channel, const char *reason) {
  gpr_log(GPR_DEBUG, "CHANNEL: unref %p %d -> %d [%s]", channel,
          channel->refs.count, channel->refs.count - 1, reason);
#else
void grpc_channel_internal_unref(grpc_channel *channel) {
#endif
  if (gpr_unref(&channel->refs)) {
    channel->destroy_closure.cb = destroy_channel;
    channel->destroy_closure.cb_arg = channel;
    grpc_iomgr_add_callback(&channel->destroy_closure);
  }
}

void grpc_channel_destroy(grpc_channel *channel) {
  grpc_transport_op op;
  grpc_channel_element *elem;
  memset(&op, 0, sizeof(op));
  op.disconnect = 1;
  elem = grpc_channel_stack_element(CHANNEL_STACK_FROM_CHANNEL(channel), 0);
  elem->filter->start_transport_op(elem, &op);

  GRPC_CHANNEL_INTERNAL_UNREF(channel, "channel");
}
Beispiel #18
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);
}
Beispiel #19
0
static void finish_destroy_channel(void *cd, int success) {
  channel_data *chand = cd;
  grpc_server *server = chand->server;
  GRPC_CHANNEL_INTERNAL_UNREF(chand->channel, "server");
  server_unref(server);
}
Beispiel #20
0
/* Create a secure client channel:
   Asynchronously: - resolve target
                   - connect to it (trying alternatives as presented)
                   - perform handshakes */
grpc_channel *grpc_secure_channel_create(grpc_channel_credentials *creds,
                                         const char *target,
                                         const grpc_channel_args *args,
                                         void *reserved) {
  grpc_channel *channel;
  grpc_arg connector_arg;
  grpc_channel_args *args_copy;
  grpc_channel_args *new_args_from_connector;
  grpc_channel_security_connector *security_connector;
  grpc_resolver *resolver;
  subchannel_factory *f;
  grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;

  GRPC_API_TRACE(
      "grpc_secure_channel_create(creds=%p, target=%s, args=%p, "
      "reserved=%p)",
      4, (creds, target, args, reserved));
  GPR_ASSERT(reserved == NULL);

  if (grpc_find_security_connector_in_args(args) != NULL) {
    gpr_log(GPR_ERROR, "Cannot set security context in channel args.");
    grpc_exec_ctx_finish(&exec_ctx);
    return grpc_lame_client_channel_create(
        target, GRPC_STATUS_INTERNAL,
        "Security connector exists in channel args.");
  }

  if (grpc_channel_credentials_create_security_connector(
          creds, target, args, &security_connector, &new_args_from_connector) !=
      GRPC_SECURITY_OK) {
    grpc_exec_ctx_finish(&exec_ctx);
    return grpc_lame_client_channel_create(
        target, GRPC_STATUS_INTERNAL, "Failed to create security connector.");
  }

  connector_arg = grpc_security_connector_to_arg(&security_connector->base);
  args_copy = grpc_channel_args_copy_and_add(
      new_args_from_connector != NULL ? new_args_from_connector : args,
      &connector_arg, 1);

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

  f = gpr_malloc(sizeof(*f));
  f->base.vtable = &subchannel_factory_vtable;
  gpr_ref_init(&f->refs, 1);
  GRPC_SECURITY_CONNECTOR_REF(&security_connector->base, "subchannel_factory");
  f->security_connector = security_connector;
  f->merge_args = grpc_channel_args_copy(args_copy);
  f->master = channel;
  GRPC_CHANNEL_INTERNAL_REF(channel, "subchannel_factory");
  resolver = grpc_resolver_create(target, &f->base);
  if (resolver) {
    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_SECURITY_CONNECTOR_UNREF(&security_connector->base, "channel_create");
  grpc_channel_args_destroy(args_copy);
  if (new_args_from_connector != NULL) {
    grpc_channel_args_destroy(new_args_from_connector);
  }

  if (!resolver) {
    GRPC_CHANNEL_INTERNAL_UNREF(&exec_ctx, channel, "subchannel_factory");
    channel = NULL;
  }
  grpc_exec_ctx_finish(&exec_ctx);

  return channel;
}