コード例 #1
0
ファイル: resource_quota.c プロジェクト: pmarks-net/grpc
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_internal_ref(resource_quota);
  grpc_closure_init(&resource_user->allocate_closure, &ru_allocate,
                    resource_user);
  grpc_closure_init(&resource_user->add_to_free_pool_closure,
                    &ru_add_to_free_pool, resource_user);
  grpc_closure_init(&resource_user->post_reclaimer_closure[0],
                    &ru_post_benign_reclaimer, resource_user);
  grpc_closure_init(&resource_user->post_reclaimer_closure[1],
                    &ru_post_destructive_reclaimer, resource_user);
  grpc_closure_init(&resource_user->destroy_closure, &ru_destroy,
                    resource_user);
  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;
  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;
}
コード例 #2
0
ファイル: tcp_client_posix.c プロジェクト: pquerna/grpc
grpc_endpoint *grpc_tcp_client_create_from_fd(
    grpc_exec_ctx *exec_ctx, grpc_fd *fd, const grpc_channel_args *channel_args,
    const char *addr_str) {
  size_t tcp_read_chunk_size = GRPC_TCP_DEFAULT_READ_SLICE_SIZE;
  grpc_resource_quota *resource_quota = grpc_resource_quota_create(NULL);
  if (channel_args != NULL) {
    for (size_t i = 0; i < channel_args->num_args; i++) {
      if (0 ==
          strcmp(channel_args->args[i].key, GRPC_ARG_TCP_READ_CHUNK_SIZE)) {
        grpc_integer_options options = {(int)tcp_read_chunk_size, 1,
                                        8 * 1024 * 1024};
        tcp_read_chunk_size = (size_t)grpc_channel_arg_get_integer(
            &channel_args->args[i], options);
      } else if (0 ==
                 strcmp(channel_args->args[i].key, GRPC_ARG_RESOURCE_QUOTA)) {
        grpc_resource_quota_internal_unref(exec_ctx, resource_quota);
        resource_quota = grpc_resource_quota_internal_ref(
            channel_args->args[i].value.pointer.p);
      }
    }
  }

  grpc_endpoint *ep =
      grpc_tcp_create(fd, resource_quota, tcp_read_chunk_size, addr_str);
  grpc_resource_quota_internal_unref(exec_ctx, resource_quota);
  return ep;
}
コード例 #3
0
ファイル: tcp_server_uv.c プロジェクト: gnirodi/grpc
grpc_error *grpc_tcp_server_create(grpc_exec_ctx *exec_ctx,
                                   grpc_closure *shutdown_complete,
                                   const grpc_channel_args *args,
                                   grpc_tcp_server **server) {
  grpc_tcp_server *s = gpr_malloc(sizeof(grpc_tcp_server));
  s->resource_quota = grpc_resource_quota_create(NULL);
  for (size_t i = 0; i < (args == NULL ? 0 : args->num_args); i++) {
    if (0 == strcmp(GRPC_ARG_RESOURCE_QUOTA, args->args[i].key)) {
      if (args->args[i].type == GRPC_ARG_POINTER) {
        grpc_resource_quota_internal_unref(exec_ctx, s->resource_quota);
        s->resource_quota =
            grpc_resource_quota_internal_ref(args->args[i].value.pointer.p);
      } else {
        grpc_resource_quota_internal_unref(exec_ctx, s->resource_quota);
        gpr_free(s);
        return GRPC_ERROR_CREATE(GRPC_ARG_RESOURCE_QUOTA
                                 " must be a pointer to a buffer pool");
      }
    }
  }
  gpr_ref_init(&s->refs, 1);
  s->on_accept_cb = NULL;
  s->on_accept_cb_arg = NULL;
  s->open_ports = 0;
  s->head = NULL;
  s->tail = NULL;
  s->shutdown_starting.head = NULL;
  s->shutdown_starting.tail = NULL;
  s->shutdown_complete = shutdown_complete;
  *server = s;
  return GRPC_ERROR_NONE;
}
コード例 #4
0
ファイル: resource_quota.c プロジェクト: pmarks-net/grpc
static void rq_step_sched(grpc_exec_ctx *exec_ctx,
                          grpc_resource_quota *resource_quota) {
  if (resource_quota->step_scheduled) return;
  resource_quota->step_scheduled = true;
  grpc_resource_quota_internal_ref(resource_quota);
  grpc_combiner_execute_finally(exec_ctx, resource_quota->combiner,
                                &resource_quota->rq_step_closure,
                                GRPC_ERROR_NONE, false);
}
コード例 #5
0
ファイル: resource_quota.c プロジェクト: pmarks-net/grpc
/* Public API */
void grpc_resource_quota_resize(grpc_resource_quota *resource_quota,
                                size_t size) {
  grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
  rq_resize_args *a = gpr_malloc(sizeof(*a));
  a->resource_quota = grpc_resource_quota_internal_ref(resource_quota);
  a->size = (int64_t)size;
  grpc_closure_init(&a->closure, rq_resize, a);
  grpc_combiner_execute(&exec_ctx, resource_quota->combiner, &a->closure,
                        GRPC_ERROR_NONE, false);
  grpc_exec_ctx_finish(&exec_ctx);
}
コード例 #6
0
ファイル: resource_quota.c プロジェクト: pmarks-net/grpc
grpc_resource_quota *grpc_resource_quota_from_channel_args(
    const grpc_channel_args *channel_args) {
  for (size_t i = 0; i < channel_args->num_args; i++) {
    if (0 == strcmp(channel_args->args[i].key, GRPC_ARG_RESOURCE_QUOTA)) {
      if (channel_args->args[i].type == GRPC_ARG_POINTER) {
        return grpc_resource_quota_internal_ref(
            channel_args->args[i].value.pointer.p);
      } else {
        gpr_log(GPR_DEBUG, GRPC_ARG_RESOURCE_QUOTA " should be a pointer");
      }
    }
  }
  return grpc_resource_quota_create(NULL);
}
コード例 #7
0
ファイル: tcp_server_posix.c プロジェクト: izouxv/grpc
grpc_error *grpc_tcp_server_create(grpc_exec_ctx *exec_ctx,
                                   grpc_closure *shutdown_complete,
                                   const grpc_channel_args *args,
                                   grpc_tcp_server **server) {
  gpr_once_init(&check_init, init);

  grpc_tcp_server *s = gpr_malloc(sizeof(grpc_tcp_server));
  s->so_reuseport = has_so_reuseport;
  s->resource_quota = grpc_resource_quota_create(NULL);
  for (size_t i = 0; i < (args == NULL ? 0 : args->num_args); i++) {
    if (0 == strcmp(GRPC_ARG_ALLOW_REUSEPORT, args->args[i].key)) {
      if (args->args[i].type == GRPC_ARG_INTEGER) {
        s->so_reuseport =
            has_so_reuseport && (args->args[i].value.integer != 0);
      } else {
        grpc_resource_quota_internal_unref(exec_ctx, s->resource_quota);
        gpr_free(s);
        return GRPC_ERROR_CREATE(GRPC_ARG_ALLOW_REUSEPORT
                                 " must be an integer");
      }
    } else if (0 == strcmp(GRPC_ARG_RESOURCE_QUOTA, args->args[i].key)) {
      if (args->args[i].type == GRPC_ARG_POINTER) {
        grpc_resource_quota_internal_unref(exec_ctx, s->resource_quota);
        s->resource_quota =
            grpc_resource_quota_internal_ref(args->args[i].value.pointer.p);
      } else {
        grpc_resource_quota_internal_unref(exec_ctx, s->resource_quota);
        gpr_free(s);
        return GRPC_ERROR_CREATE(GRPC_ARG_RESOURCE_QUOTA
                                 " must be a pointer to a buffer pool");
      }
    }
  }
  gpr_ref_init(&s->refs, 1);
  gpr_mu_init(&s->mu);
  s->active_ports = 0;
  s->destroyed_ports = 0;
  s->shutdown = false;
  s->shutdown_starting.head = NULL;
  s->shutdown_starting.tail = NULL;
  s->shutdown_complete = shutdown_complete;
  s->on_accept_cb = NULL;
  s->on_accept_cb_arg = NULL;
  s->head = NULL;
  s->tail = NULL;
  s->nports = 0;
  gpr_atm_no_barrier_store(&s->next_pollset_to_assign, 0);
  *server = s;
  return GRPC_ERROR_NONE;
}
コード例 #8
0
ファイル: resource_quota.c プロジェクト: pmarks-net/grpc
/* returns true if reclamation is proceeding */
static bool rq_reclaim(grpc_exec_ctx *exec_ctx,
                       grpc_resource_quota *resource_quota, bool destructive) {
  if (resource_quota->reclaiming) return true;
  grpc_rulist list = destructive ? GRPC_RULIST_RECLAIMER_DESTRUCTIVE
                                 : GRPC_RULIST_RECLAIMER_BENIGN;
  grpc_resource_user *resource_user = rulist_pop_head(resource_quota, list);
  if (resource_user == NULL) return false;
  if (grpc_resource_quota_trace) {
    gpr_log(GPR_DEBUG, "RQ %s %s: initiate %s reclamation",
            resource_quota->name, resource_user->name,
            destructive ? "destructive" : "benign");
  }
  resource_quota->reclaiming = true;
  grpc_resource_quota_internal_ref(resource_quota);
  grpc_closure *c = resource_user->reclaimers[destructive];
  resource_user->reclaimers[destructive] = NULL;
  grpc_closure_run(exec_ctx, c, GRPC_ERROR_NONE);
  return true;
}
コード例 #9
0
ファイル: resource_quota.c プロジェクト: pmarks-net/grpc
/* Public API */
void grpc_resource_quota_ref(grpc_resource_quota *resource_quota) {
  grpc_resource_quota_internal_ref(resource_quota);
}
コード例 #10
0
ファイル: tcp_client_windows.c プロジェクト: pquerna/grpc
/* Tries to issue one async connection, then schedules both an IOCP
   notification request for the connection, and one timeout alert. */
void grpc_tcp_client_connect(grpc_exec_ctx *exec_ctx, grpc_closure *on_done,
                             grpc_endpoint **endpoint,
                             grpc_pollset_set *interested_parties,
                             const grpc_channel_args *channel_args,
                             const grpc_resolved_address *addr,
                             gpr_timespec deadline) {
  SOCKET sock = INVALID_SOCKET;
  BOOL success;
  int status;
  grpc_resolved_address addr6_v4mapped;
  grpc_resolved_address local_address;
  async_connect *ac;
  grpc_winsocket *socket = NULL;
  LPFN_CONNECTEX ConnectEx;
  GUID guid = WSAID_CONNECTEX;
  DWORD ioctl_num_bytes;
  grpc_winsocket_callback_info *info;
  grpc_error *error = GRPC_ERROR_NONE;

  grpc_resource_quota *resource_quota = grpc_resource_quota_create(NULL);
  if (channel_args != NULL) {
    for (size_t i = 0; i < channel_args->num_args; i++) {
      if (0 == strcmp(channel_args->args[i].key, GRPC_ARG_RESOURCE_QUOTA)) {
        grpc_resource_quota_internal_unref(exec_ctx, resource_quota);
        resource_quota = grpc_resource_quota_internal_ref(
            channel_args->args[i].value.pointer.p);
      }
    }
  }

  *endpoint = NULL;

  /* Use dualstack sockets where available. */
  if (grpc_sockaddr_to_v4mapped(addr, &addr6_v4mapped)) {
    addr = &addr6_v4mapped;
  }

  sock = WSASocket(AF_INET6, SOCK_STREAM, IPPROTO_TCP, NULL, 0,
                   WSA_FLAG_OVERLAPPED);
  if (sock == INVALID_SOCKET) {
    error = GRPC_WSA_ERROR(WSAGetLastError(), "WSASocket");
    goto failure;
  }

  error = grpc_tcp_prepare_socket(sock);
  if (error != GRPC_ERROR_NONE) {
    goto failure;
  }

  /* Grab the function pointer for ConnectEx for that specific socket.
     It may change depending on the interface. */
  status =
      WSAIoctl(sock, SIO_GET_EXTENSION_FUNCTION_POINTER, &guid, sizeof(guid),
               &ConnectEx, sizeof(ConnectEx), &ioctl_num_bytes, NULL, NULL);

  if (status != 0) {
    error = GRPC_WSA_ERROR(WSAGetLastError(),
                           "WSAIoctl(SIO_GET_EXTENSION_FUNCTION_POINTER)");
    goto failure;
  }

  grpc_sockaddr_make_wildcard6(0, &local_address);

  status = bind(sock, (struct sockaddr *)&local_address.addr,
                (int)local_address.len);
  if (status != 0) {
    error = GRPC_WSA_ERROR(WSAGetLastError(), "bind");
    goto failure;
  }

  socket = grpc_winsocket_create(sock, "client");
  info = &socket->write_info;
  success = ConnectEx(sock, (struct sockaddr *)&addr->addr, (int)addr->len,
                      NULL, 0, NULL, &info->overlapped);

  /* It wouldn't be unusual to get a success immediately. But we'll still get
     an IOCP notification, so let's ignore it. */
  if (!success) {
    int last_error = WSAGetLastError();
    if (last_error != ERROR_IO_PENDING) {
      error = GRPC_WSA_ERROR(last_error, "ConnectEx");
      goto failure;
    }
  }

  ac = gpr_malloc(sizeof(async_connect));
  ac->on_done = on_done;
  ac->socket = socket;
  gpr_mu_init(&ac->mu);
  ac->refs = 2;
  ac->addr_name = grpc_sockaddr_to_uri(addr);
  ac->endpoint = endpoint;
  ac->resource_quota = resource_quota;
  grpc_closure_init(&ac->on_connect, on_connect, ac);

  grpc_timer_init(exec_ctx, &ac->alarm, deadline, on_alarm, ac,
                  gpr_now(GPR_CLOCK_MONOTONIC));
  grpc_socket_notify_on_write(exec_ctx, socket, &ac->on_connect);
  return;

failure:
  GPR_ASSERT(error != GRPC_ERROR_NONE);
  char *target_uri = grpc_sockaddr_to_uri(addr);
  grpc_error *final_error = grpc_error_set_str(
      GRPC_ERROR_CREATE_REFERENCING("Failed to connect", &error, 1),
      GRPC_ERROR_STR_TARGET_ADDRESS, target_uri);
  GRPC_ERROR_UNREF(error);
  if (socket != NULL) {
    grpc_winsocket_destroy(socket);
  } else if (sock != INVALID_SOCKET) {
    closesocket(sock);
  }
  grpc_resource_quota_internal_unref(exec_ctx, resource_quota);
  grpc_exec_ctx_sched(exec_ctx, on_done, final_error, NULL);
}