Ejemplo n.º 1
0
AsyncStatus
asyncConnector_run(AsyncConnector* ac)
{
    switch (ac->state) {
    case CONNECT_ERROR:
        errno = ac->error;
        return ASYNC_ERROR;

    case CONNECT_CONNECTING:
        loopIo_dontWantWrite(ac->io);
        /* We need to read the socket error to determine if
            * the connection was really succesful or not. This
            * is optional, because in case of error a future
            * socket_recv() or socket_send() will fail anyway, but this
            * allows us to get a better error value as soon as
            * possible.
            */
        ac->error = socket_get_error(ac->io->fd);
        if (ac->error == 0) {
            ac->state = CONNECT_COMPLETED;
            return ASYNC_COMPLETE;
        }
        ac->state = CONNECT_ERROR;
        errno = ac->error;
        return ASYNC_ERROR;

    default:
        return ASYNC_COMPLETE;
    }
}
Ejemplo n.º 2
0
GError*
gridd_client_step(struct client_s *client)
{
	struct pollfd pfd = {-1, 0, 0};

	if (!_client_to_pollfd(client, &pfd)) {
		return NULL;
	}

	int rc = metautils_syscall_poll(&pfd, 1, 1000);
	if (rc == 0) {
		GTimeVal now;
		g_get_current_time(&now);
		gridd_client_expire(client, &now);
		return NULL;
	}
	if (rc < 0)
		return NEWERROR(errno, "poll errno=%d %s", errno, strerror(errno));

	if (pfd.revents & POLLERR) {
		GError *err = socket_get_error(pfd.fd);
		g_prefix_error(&err, "%s: ", gridd_client_url(client));
		gridd_client_fail(client, err);
		g_clear_error(&err);
	}
	else
		gridd_client_react(client);
	return NULL;
}
Ejemplo n.º 3
0
GError*
gridd_client_step(struct gridd_client_s *client)
{
	int rc;
	struct pollfd pfd = {-1, 0, 0};

	if (!_client_to_pollfd(client, &pfd))
		return NULL;

retry:
	rc = metautils_syscall_poll(&pfd, 1, 1000);
	if (rc == 0) {
		gridd_client_expire(client, oio_ext_monotonic_time ());
		return NULL;
	}
	if (rc < 0) {
		if (errno == EINTR) goto retry;
		return NEWERROR(errno, "poll errno=%d %s", errno, strerror(errno));
	}

	if (pfd.revents & POLLERR) {
		GError *err = socket_get_error(pfd.fd);
		g_prefix_error(&err, "%s: ", gridd_client_url(client));
		gridd_client_fail(client, err);
		g_clear_error(&err);
	}
	else if (pfd.revents & (POLLIN|POLLOUT)) {
		gridd_client_react(client);
	}
	return NULL;
}
Ejemplo n.º 4
0
static void tcp_wait_for_connect(void *opaque)
{
    FdMigrationState *s = opaque;
    int ret;

    dprintf("connect completed\n");
    ret = socket_get_error(s->fd);
    if (ret < 0) {
        dprintf("error connecting %d\n", val);
        migrate_fd_error(s);
        return;
    }

    qemu_set_fd_handler2(s->fd, NULL, NULL, NULL, NULL);

    migrate_fd_connect(s);
}
Ejemplo n.º 5
0
int Socket::read(char* buffer, int nbytes) {
    
  int err;
  int r;
  int chunk_size = 1024;

  if (NULL == buffer) {
    RX_ERROR("Trying to read into NULL buffer.");
    return -1;
  }
  if (0 == nbytes) {
    RX_ERROR("Buffer size is 0. No way we can read into that.");
    return -2;
  }

  if (0 != isConnected()) {
    return -3;
  }

  r = recv(handle, buffer, nbytes, 0);

  if (r < 0) {
    err = socket_get_error();
    if (0 == socket_is_recoverable_error(err)) {
      return 0;
    }

    RX_ERROR("Could not read data from socket: %s", strerror(errno));
    close();
    return -4;
  }

  if (0 == r) {
    close();
    return -5;
  }

//  if (NULL != listener) {
//    listener->onSocketRead(buffer, r);
//  }
  return r;
}
Ejemplo n.º 6
0
int Socket::close() {

  /* Already closed? */
  if (0 != isConnected()) {
    return 0; 
  }

  /* Close */
  if (-1 != handle) {
    errno = EINTR;
#if defined(_WIN32)      
    int result = -1;
    int err = 0;
    do { 

      result = ::closesocket(handle);
      handle = -1; /* event when closesocket returns < 0, we unset the handle so we can reuse it. */

      if (0 != result) {

        err = socket_get_error();

        switch(err) {
          case WSANOTINITIALISED: {
            RX_ERROR("Socket not initialized.");
            return 0;
          }
          case WSAENETDOWN: {
            RX_ERROR("Network is down. Socket closed");
            return 0;
          }
          case WSAENOTSOCK: {
            RX_ERROR("The `sock` member is not a real socket. This is not supposed to happen but occurs when connect() fails.");
            return 0;
          }
          case WSAEINPROGRESS: {
            RX_VERBOSE("We're in the process of closing the socket; continuing.");
            return 0;
          }
          case WSAEINTR: {
            RX_VERBOSE("Call was interrupted.");
            return 0;
          }
          case WSAEWOULDBLOCK: {
            RX_ERROR("WSAWOULDBLOCK");
            return 0;
          }
          default: {
            RX_ERROR("Unhandled error in close(), error: %d", err);
            return 0;
          }
        }
      }
    } while (0 != result);
#else
    while (::close(handle) != 0 && EINTR == errno) { }
#endif
    handle = -1;
  }

  return 0;
}
Ejemplo n.º 7
0
int Socket::send(const char* data, int nbytes) {

  int err = 0;
  int done = 0;

  if (NULL == data) {
    RX_ERROR("Trying to send NULL data.");
    return -1;
  }

  if (0 == nbytes) {
    RX_ERROR("Trying to send 0 bytes.");
    return -2;
  }

  if (0 != isConnected()) {
    RX_ERROR("Cannot send because we're not connected.");
    return -3;
  }

  while (nbytes > 0 && 0 == isConnected()) {
#if defined(_WIN32)      
    done = ::send(handle, (const char*) data, nbytes, 0);
#else
    done = ::send(handle, (const void*) data, nbytes, 0);
#endif

    if (done != nbytes) {

      /* @todo implement the situation where we couldn't send all bytes. */
      RX_ERROR("Failed to send all bytes, this is a situation we need to handle correctly. We sent: %d, but should: %lu.", done, nbytes);

      err = socket_get_error();
      if (0 == socket_is_recoverable_error(err)) {
        RX_ERROR("The error is recoverable.");
        return -4;
      }
      else {
        close();
        return -5;
      }
    }

    if (done < 0) {
      err = socket_get_error();
      if (0 == socket_is_recoverable_error(err)) {
        return 0;
      }

      RX_ERROR("Error while sending data over socket: %s", strerror(errno));

      if (0 != close()) {
        RX_ERROR("Failed to cleanly close the socket after being disconnected.");
      }

      if (NULL != listener) {
        listener->onSocketDisconnected();
      }

      return -3;
    }
      
    nbytes -= done;
  }

  return 0;
}
Ejemplo n.º 8
0
GError *
gridd_clients_step(struct client_s **clients)
{
	struct client_s ** _lookup_client(int fd, struct client_s **ppc) {
		struct client_s *c;
		for (; (c = *ppc) ;ppc++) {
			if (gridd_client_fd(c) == fd)
				return ppc;
		}
		return ppc;
	}

	guint i, j;
	int rc;
	struct client_s *last, **plast;
	GTimeVal now;
	guint nbclients;

	EXTRA_ASSERT(clients != NULL);
	nbclients = g_strv_length((gchar**)clients);
	EXTRA_ASSERT(nbclients > 0);

	struct pollfd pfd[nbclients];

	for (j=0,plast=clients; NULL != (last = *plast) ;plast++) {
		if (_client_to_pollfd(last, pfd+j))
			j++;
	}
	if (!j)
		return NULL;

	/* Wait for an event to happen */
	if (!(rc = poll(pfd, j, 100))) {
		g_get_current_time(&now);
		_clients_expire(clients, &now);
		return NULL;
	}
	if (rc < 0)
		return NEWERROR(errno, "poll error (%s)", strerror(errno));

	/* Then manage each event */
	for (plast=clients,i=0; i<j ;i++) {
		if (!pfd[i].revents)
			continue;

		/* Find the client for this pollfd */
		plast = _lookup_client(pfd[i].fd, plast);
		EXTRA_ASSERT(plast != NULL);
		last = *plast;

		/* Manage the poll() event */
		if (pfd[i].revents & POLLERR) {
			GError *err = socket_get_error(pfd[i].fd);
			g_prefix_error(&err, "%s: ", gridd_client_url(last));
			gridd_client_fail(last, err);
			g_clear_error(&err);
		}
		else
			gridd_client_react(last);
	}

	/* Now check for expired clients */
	g_get_current_time(&now);
	_clients_expire(clients, &now);
	return NULL;
}