Ejemplo n.º 1
0
/* Public API */
grpc_resource_quota *grpc_resource_quota_create(const char *name) {
  grpc_resource_quota *resource_quota = gpr_malloc(sizeof(*resource_quota));
  gpr_ref_init(&resource_quota->refs, 1);
  resource_quota->combiner = grpc_combiner_create(NULL);
  resource_quota->free_pool = INT64_MAX;
  resource_quota->size = INT64_MAX;
  resource_quota->step_scheduled = false;
  resource_quota->reclaiming = false;
  gpr_atm_no_barrier_store(&resource_quota->memory_usage_estimation, 0);
  if (name != NULL) {
    resource_quota->name = gpr_strdup(name);
  } else {
    gpr_asprintf(&resource_quota->name, "anonymous_pool_%" PRIxPTR,
                 (intptr_t)resource_quota);
  }
  grpc_closure_init(
      &resource_quota->rq_step_closure, rq_step, resource_quota,
      grpc_combiner_finally_scheduler(resource_quota->combiner, true));
  grpc_closure_init(&resource_quota->rq_reclamation_done_closure,
                    rq_reclamation_done, resource_quota,
                    grpc_combiner_scheduler(resource_quota->combiner, false));
  for (int i = 0; i < GRPC_RULIST_COUNT; i++) {
    resource_quota->roots[i] = NULL;
  }
  return resource_quota;
}
Ejemplo n.º 2
0
void grpc_fake_resolver_response_generator_set_response(
    grpc_exec_ctx* exec_ctx, grpc_fake_resolver_response_generator* generator,
    grpc_channel_args* next_response) {
  GPR_ASSERT(generator->resolver != NULL);
  generator->next_response = grpc_channel_args_copy(next_response);
  GRPC_CLOSURE_SCHED(
      exec_ctx, GRPC_CLOSURE_CREATE(set_response_cb, generator,
                                    grpc_combiner_scheduler(
                                        generator->resolver->base.combiner)),
      GRPC_ERROR_NONE);
}
Ejemplo n.º 3
0
void grpc_resource_user_shutdown(grpc_exec_ctx *exec_ctx,
                                 grpc_resource_user *resource_user) {
  if (gpr_atm_full_fetch_add(&resource_user->shutdown, 1) == 0) {
    grpc_closure_sched(exec_ctx,
                       grpc_closure_create(
                           ru_shutdown, resource_user,
                           grpc_combiner_scheduler(
                               resource_user->resource_quota->combiner, false)),
                       GRPC_ERROR_NONE);
  }
}
Ejemplo n.º 4
0
grpc_resource_user *grpc_resource_user_create(
    grpc_resource_quota *resource_quota, const char *name) {
  grpc_resource_user *resource_user = gpr_malloc(sizeof(*resource_user));
  resource_user->resource_quota =
      grpc_resource_quota_ref_internal(resource_quota);
  grpc_closure_init(&resource_user->allocate_closure, &ru_allocate,
                    resource_user,
                    grpc_combiner_scheduler(resource_quota->combiner, false));
  grpc_closure_init(&resource_user->add_to_free_pool_closure,
                    &ru_add_to_free_pool, resource_user,
                    grpc_combiner_scheduler(resource_quota->combiner, false));
  grpc_closure_init(&resource_user->post_reclaimer_closure[0],
                    &ru_post_benign_reclaimer, resource_user,
                    grpc_combiner_scheduler(resource_quota->combiner, false));
  grpc_closure_init(&resource_user->post_reclaimer_closure[1],
                    &ru_post_destructive_reclaimer, resource_user,
                    grpc_combiner_scheduler(resource_quota->combiner, false));
  grpc_closure_init(&resource_user->destroy_closure, &ru_destroy, resource_user,
                    grpc_combiner_scheduler(resource_quota->combiner, false));
  gpr_mu_init(&resource_user->mu);
  gpr_atm_rel_store(&resource_user->refs, 1);
  gpr_atm_rel_store(&resource_user->shutdown, 0);
  resource_user->free_pool = 0;
  grpc_closure_list_init(&resource_user->on_allocated);
  resource_user->allocating = false;
  resource_user->added_to_free_pool = false;
  resource_user->reclaimers[0] = NULL;
  resource_user->reclaimers[1] = NULL;
  resource_user->new_reclaimers[0] = NULL;
  resource_user->new_reclaimers[1] = NULL;
  for (int i = 0; i < GRPC_RULIST_COUNT; i++) {
    resource_user->links[i].next = resource_user->links[i].prev = NULL;
  }
  if (name != NULL) {
    resource_user->name = gpr_strdup(name);
  } else {
    gpr_asprintf(&resource_user->name, "anonymous_resource_user_%" PRIxPTR,
                 (intptr_t)resource_user);
  }
  return resource_user;
}
Ejemplo n.º 5
0
static void call_resolver_next_after_locking(grpc_exec_ctx *exec_ctx,
                                             grpc_resolver *resolver,
                                             grpc_channel_args **result,
                                             grpc_closure *on_complete) {
  next_args *a = gpr_malloc(sizeof(*a));
  a->resolver = resolver;
  a->result = result;
  a->on_complete = on_complete;
  GRPC_CLOSURE_SCHED(exec_ctx, GRPC_CLOSURE_CREATE(
                                   call_resolver_next_now_lock_taken, a,
                                   grpc_combiner_scheduler(resolver->combiner)),
                     GRPC_ERROR_NONE);
}
Ejemplo n.º 6
0
static void test_fake_resolver() {
  grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
  grpc_combiner *combiner = grpc_combiner_create(NULL);
  // Create resolver.
  grpc_fake_resolver_response_generator *response_generator =
      grpc_fake_resolver_response_generator_create();
  grpc_resolver *resolver =
      build_fake_resolver(&exec_ctx, combiner, response_generator);
  GPR_ASSERT(resolver != NULL);

  // Setup expectations.
  grpc_uri *uris[] = {grpc_uri_parse(&exec_ctx, "ipv4:10.2.1.1:1234", true),
                      grpc_uri_parse(&exec_ctx, "ipv4:127.0.0.1:4321", true)};
  char *balancer_names[] = {"name1", "name2"};
  const bool is_balancer[] = {true, false};
  grpc_lb_addresses *addresses = grpc_lb_addresses_create(3, NULL);
  for (size_t i = 0; i < GPR_ARRAY_SIZE(uris); ++i) {
    grpc_lb_addresses_set_address_from_uri(
        addresses, i, uris[i], is_balancer[i], balancer_names[i], NULL);
    grpc_uri_destroy(uris[i]);
  }
  const grpc_arg addresses_arg =
      grpc_lb_addresses_create_channel_arg(addresses);
  grpc_channel_args *results =
      grpc_channel_args_copy_and_add(NULL, &addresses_arg, 1);
  grpc_lb_addresses_destroy(&exec_ctx, addresses);
  on_resolution_arg on_res_arg;
  memset(&on_res_arg, 0, sizeof(on_res_arg));
  on_res_arg.expected_resolver_result = results;
  grpc_closure *on_resolution = grpc_closure_create(
      on_resolution_cb, &on_res_arg, grpc_combiner_scheduler(combiner, false));

  // Set resolver results and trigger first resolution. on_resolution_cb
  // performs the checks.
  grpc_fake_resolver_response_generator_set_response(
      &exec_ctx, response_generator, results);
  grpc_resolver_next_locked(&exec_ctx, resolver, &on_res_arg.resolver_result,
                            on_resolution);
  grpc_exec_ctx_flush(&exec_ctx);
  GPR_ASSERT(on_res_arg.was_called);

  // Setup update.
  grpc_uri *uris_update[] = {
      grpc_uri_parse(&exec_ctx, "ipv4:192.168.1.0:31416", true)};
  char *balancer_names_update[] = {"name3"};
  const bool is_balancer_update[] = {false};
  grpc_lb_addresses *addresses_update = grpc_lb_addresses_create(1, NULL);
  for (size_t i = 0; i < GPR_ARRAY_SIZE(uris_update); ++i) {
    grpc_lb_addresses_set_address_from_uri(addresses_update, i, uris_update[i],
                                           is_balancer_update[i],
                                           balancer_names_update[i], NULL);
    grpc_uri_destroy(uris_update[i]);
  }

  grpc_arg addresses_update_arg =
      grpc_lb_addresses_create_channel_arg(addresses_update);
  grpc_channel_args *results_update =
      grpc_channel_args_copy_and_add(NULL, &addresses_update_arg, 1);
  grpc_lb_addresses_destroy(&exec_ctx, addresses_update);

  // Setup expectations for the update.
  on_resolution_arg on_res_arg_update;
  memset(&on_res_arg_update, 0, sizeof(on_res_arg_update));
  on_res_arg_update.expected_resolver_result = results_update;
  on_resolution = grpc_closure_create(on_resolution_cb, &on_res_arg_update,
                                      grpc_combiner_scheduler(combiner, false));

  // Set updated resolver results and trigger a second resolution.
  grpc_fake_resolver_response_generator_set_response(
      &exec_ctx, response_generator, results_update);
  grpc_resolver_next_locked(&exec_ctx, resolver,
                            &on_res_arg_update.resolver_result, on_resolution);
  grpc_exec_ctx_flush(&exec_ctx);
  GPR_ASSERT(on_res_arg.was_called);

  // Requesting a new resolution without re-senting the response shouldn't
  // trigger the resolution callback.
  memset(&on_res_arg, 0, sizeof(on_res_arg));
  grpc_resolver_next_locked(&exec_ctx, resolver, &on_res_arg.resolver_result,
                            on_resolution);
  grpc_exec_ctx_flush(&exec_ctx);
  GPR_ASSERT(!on_res_arg.was_called);

  GRPC_COMBINER_UNREF(&exec_ctx, combiner, "test_fake_resolver");
  GRPC_RESOLVER_UNREF(&exec_ctx, resolver, "test_fake_resolver");
  grpc_exec_ctx_finish(&exec_ctx);
  grpc_fake_resolver_response_generator_unref(response_generator);
}