Пример #1
0
/* Public function. Stops and destroys a grpc_tcp_server. */
void grpc_tcp_server_destroy(grpc_tcp_server *s,
                             void (*shutdown_done)(void *shutdown_done_arg),
                             void *shutdown_done_arg) {
  size_t i;
  gpr_mu_lock(&s->mu);
  /* First, shutdown all fd's. This will queue abortion calls for all
     of the pending accepts. */
  for (i = 0; i < s->nports; i++) {
    server_port *sp = &s->ports[i];
    grpc_winsocket_shutdown(sp->socket);
  }
  /* This happens asynchronously. Wait while that happens. */
  while (s->active_ports) {
    gpr_cv_wait(&s->cv, &s->mu, gpr_inf_future);
  }
  gpr_mu_unlock(&s->mu);

  /* Now that the accepts have been aborted, we can destroy the sockets.
     The IOCP won't get notified on these, so we can flag them as already
     closed by the system. */
  for (i = 0; i < s->nports; i++) {
    server_port *sp = &s->ports[i];
    sp->socket->closed_early = 1;
    grpc_winsocket_orphan(sp->socket);
  }
  gpr_free(s->ports);
  gpr_free(s);

  if (shutdown_done) {
    shutdown_done(shutdown_done_arg);
  }
}
Пример #2
0
static void tcp_unref(grpc_tcp *tcp) {
  if (gpr_unref(&tcp->refcount)) {
    gpr_slice_buffer_destroy(&tcp->write_slices);
    grpc_winsocket_orphan(tcp->socket);
    gpr_mu_destroy(&tcp->mu);
    gpr_free(tcp);
  }
}
Пример #3
0
static void on_connect(void *acp, int success) {
  async_connect *ac = acp;
  SOCKET sock = ac->socket->socket;
  grpc_endpoint *ep = NULL;
  grpc_winsocket_callback_info *info = &ac->socket->write_info;
  void(*cb)(void *arg, grpc_endpoint *tcp) = ac->cb;
  void *cb_arg = ac->cb_arg;

  grpc_alarm_cancel(&ac->alarm);

  if (success) {
    DWORD transfered_bytes = 0;
    DWORD flags;
    BOOL wsa_success = WSAGetOverlappedResult(sock, &info->overlapped,
                                              &transfered_bytes, FALSE,
                                              &flags);
    GPR_ASSERT(transfered_bytes == 0);
    if (!wsa_success) {
      char *utf8_message = gpr_format_message(WSAGetLastError());
      gpr_log(GPR_ERROR, "on_connect error: %s", utf8_message);
      gpr_free(utf8_message);
      goto finish;
    } else {
      ep = grpc_tcp_create(ac->socket);
      goto finish;
    }
  } else {
    gpr_log(GPR_ERROR, "on_connect is shutting down");
    goto finish;
  }

  abort();

finish:
  gpr_mu_lock(&ac->mu);
  if (!ep) {
    grpc_winsocket_orphan(ac->socket);
  }
  async_connect_cleanup(ac);
  cb(cb_arg, ep);
}
Пример #4
0
void grpc_tcp_server_destroy(grpc_tcp_server *s) {
  size_t i;
  gpr_mu_lock(&s->mu);
  /* shutdown all fd's */
  for (i = 0; i < s->nports; i++) {
    grpc_winsocket_shutdown(s->ports[i].socket);
  }
  /* wait while that happens */
  while (s->active_ports) {
    gpr_cv_wait(&s->cv, &s->mu, gpr_inf_future);
  }
  gpr_mu_unlock(&s->mu);

  /* delete ALL the things */
  for (i = 0; i < s->nports; i++) {
    server_port *sp = &s->ports[i];
    grpc_winsocket_orphan(sp->socket);
  }
  gpr_free(s->ports);
  gpr_free(s);
}
Пример #5
0
void grpc_tcp_client_connect(void(*cb)(void *arg, grpc_endpoint *tcp),
                             void *arg, const struct sockaddr *addr,
                             int addr_len, gpr_timespec deadline) {
  SOCKET sock = INVALID_SOCKET;
  BOOL success;
  int status;
  struct sockaddr_in6 addr6_v4mapped;
  struct sockaddr_in6 local_address;
  async_connect *ac;
  grpc_winsocket *socket = NULL;
  LPFN_CONNECTEX ConnectEx;
  GUID guid = WSAID_CONNECTEX;
  DWORD ioctl_num_bytes;
  const char *message = NULL;
  char *utf8_message;
  grpc_winsocket_callback_info *info;

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

  sock = WSASocket(AF_INET6, SOCK_STREAM, IPPROTO_TCP, NULL, 0,
                   WSA_FLAG_OVERLAPPED);
  if (sock == INVALID_SOCKET) {
    message = "Unable to create socket: %s";
    goto failure;
  }

  if (!grpc_tcp_prepare_socket(sock)) {
    message = "Unable to set socket options: %s";
    goto failure;
  }

  status = WSAIoctl(sock, SIO_GET_EXTENSION_FUNCTION_POINTER,
                    &guid, sizeof(guid), &ConnectEx, sizeof(ConnectEx),
                    &ioctl_num_bytes, NULL, NULL);

  if (status != 0) {
    message = "Unable to retreive ConnectEx pointer: %s";
    goto failure;
  }

  grpc_sockaddr_make_wildcard6(0, &local_address);

  status = bind(sock, (struct sockaddr *) &local_address,
                sizeof(local_address));
  if (status != 0) {
    message = "Unable to bind socket: %s";
    goto failure;
  }

  socket = grpc_winsocket_create(sock);
  info = &socket->write_info;
  success = ConnectEx(sock, addr, addr_len, NULL, 0, NULL, &info->overlapped);

  if (!success) {
    int error = WSAGetLastError();
    if (error != ERROR_IO_PENDING) {
      message = "ConnectEx failed: %s";
      goto failure;
    }
  }

  ac = gpr_malloc(sizeof(async_connect));
  ac->cb = cb;
  ac->cb_arg = arg;
  ac->socket = socket;
  gpr_mu_init(&ac->mu);
  ac->refs = 2;

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

failure:
  utf8_message = gpr_format_message(WSAGetLastError());
  gpr_log(GPR_ERROR, message, utf8_message);
  gpr_free(utf8_message);
  if (socket) {
    grpc_winsocket_orphan(socket);
  } else if (sock != INVALID_SOCKET) {
    closesocket(sock);
  }
  cb(arg, NULL);
}
Пример #6
0
static void tcp_free(grpc_tcp *tcp) {
  grpc_winsocket_orphan(tcp->socket);
  gpr_mu_destroy(&tcp->mu);
  gpr_free(tcp->peer_string);
  gpr_free(tcp);
}