Пример #1
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;
}
Пример #2
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;
}
static int
_send (int fd, struct iovec *iov, unsigned int iovcount)
{
	int w;
retry:
	w = writev (fd, iov, iovcount);
	if (w < 0) {
		if (errno == EINTR)
			goto retry;
		if (errno == EAGAIN || errno == EWOULDBLOCK) {
			struct pollfd pfd = {0};
			pfd.fd = fd;
			pfd.events = POLLOUT;
			metautils_syscall_poll (&pfd, 1, 1000);
			goto retry;
		}
		GRID_WARN("BEANSTALKD failed to put: [errno=%d] %s",
				errno, strerror(errno));
		return 0;
	}

	while (w > 0 && iovcount > 0) {
		if (iov[0].iov_len <= (size_t)w) {
			w -= iov[0].iov_len;
			iov[0].iov_len = 0;
			iov ++;
			iovcount --;
		} else {
			iov[0].iov_len -= w;
			w = 0;
		}
	}
	if (iovcount > 0)
		goto retry;

	GRID_TRACE("BEANSTALKD put sent!");
	return 1;
}
Пример #4
0
gint
sock_to_read(int fd, gint ms, void *buf, gsize bufSize, GError ** err)
{
	if (VTABLE.to_read)
		return VTABLE.to_read(fd, ms, buf, bufSize, err);

#define READ() do { \
		rc = metautils_syscall_read(fd, buf, bufSize); \
		if (rc > 0) \
			return rc; \
		if (rc == 0) { \
			GSETCODE(err, ERRCODE_CONN_CLOSED, "Socket %d closed", fd); \
			return 0; \
		} \
		if (errno != EAGAIN && errno != EINTR) { \
			GSETCODE(err, errno_to_errcode(errno), "Read error (%s)", strerror(errno)); \
			return -1; \
		} \
	} while (0)

	gint rc;

	if (fd < 0 || !buf || bufSize <= 0) {
		GSETERROR(err, "invalid parameter");
		return -1;
	}

	/* on tente un premier READ, qui s'il reussit, nous epargne un appel a POLL */
	READ();

	/* pas de data en attente, donc attente protegee par le poll */
	for (;;) {
		struct pollfd p;

		p.fd = fd;
		p.events = POLLIN;
		p.revents = 0;

		/*wait for something to happen */
		rc = metautils_syscall_poll(&p, 1, ms);
		if (rc == 0) {	/*timeout */
			GSETCODE(err, ERRCODE_CONN_TIMEOUT, "Socket timeout");
			return -1;
		}

		if (rc < 0 && errno != EINTR) {	/*error */
			GSETCODE(err, errno_to_errcode(errno), "Socket error (%s)", strerror(errno));
			return -1;
		}
		if (rc == 1) {
			if (p.revents & POLLHUP && !(p.revents & POLLIN)) {
				GSETCODE(err, ERRCODE_CONN_CLOSED, "Socket %d closed", fd);
				return 0;
			}
			if (p.revents & POLLERR) {
				int sock_err = socket_get_errcode(fd);
				GSETCODE(err, ERRCODE_CONN_CLOSED, "Socket %d error : (%d) %s", fd, sock_err, strerror(sock_err));
				return 0;
			}
			READ();
		}
	}
}
Пример #5
0
gint
sock_to_write(int fd, gint ms, void *buf, gsize bufSize, GError ** err)
{
	if (VTABLE.to_write)
		return VTABLE.to_write(fd, ms, buf, bufSize, err);

#define WRITE() do { \
		written = metautils_syscall_write(fd, ((guint8 *)buf) + nbSent, bufSize - nbSent); \
		if (written > 0) { \
			ui_written = written; \
			nbSent += ui_written; \
		} \
		if (written < 0) { \
			if (errno != EAGAIN && errno != EINTR) { \
				GSETERROR(err, "Write error (%s)", strerror(errno)); \
				return -1; \
			} \
		} \
} while (0)

	gsize ui_written;
	ssize_t written;
	gsize nbSent = 0;

	if (fd < 0 || !buf || bufSize <= 0) {
		GSETERROR(err, "invalid parameter");
		return -1;
	}

	WRITE();

	while (nbSent < bufSize) {
		int rc_poll;
		struct pollfd p;

		p.fd = fd;
		p.events = POLLOUT | POLLERR | POLLHUP | POLLNVAL;
		p.revents = 0;

		errno = 0;
		rc_poll = metautils_syscall_poll(&p, 1, ms);

		if (rc_poll == 0) {	/*timeout */
			GSETCODE(err, ERRCODE_CONN_TIMEOUT, "Socket timeout");
			return (-1);
		}

		if (rc_poll == -1) {	/*poll error */
			if (errno != EINTR) {
				GSETERROR(err, "Socket error (%s) after %"G_GSIZE_FORMAT" bytes written", strerror(errno), nbSent);
				return (-1);
			}
			else {
				TRACE("poll interrupted (%s)", strerror(errno));
				continue;
			}
		}

		/*poll success */
		if (p.revents & POLLNVAL) {
			GSETERROR(err, "Socket (%d) is invalid after %"G_GSIZE_FORMAT" bytes sent", fd, nbSent);
			return -1;
		}
		if (p.revents & POLLERR) {
			int sock_err = socket_get_errcode(fd);
			GSETERROR(err, "Socket (%d) error after %"G_GSIZE_FORMAT" bytes written : (%d) %s", fd, nbSent, sock_err, strerror(sock_err));
			return -1;
		}
		if ((p.revents & POLLHUP)) {
			GSETCODE(err, ERRCODE_CONN_CLOSED, "Socket (%d) closed after %"G_GSIZE_FORMAT" bytes written", fd, nbSent);
			return -1;
		}

		WRITE();
	}

	return nbSent;
}
Пример #6
0
GError *
gridd_clients_step(struct gridd_client_s **clients)
{
	struct gridd_client_s ** _lookup_client(int fd, struct gridd_client_s **ppc) {
		struct gridd_client_s *c;
		for (; (c = *ppc) ;ppc++) {
			if (gridd_client_fd(c) == fd)
				return ppc;
		}
		return ppc;
	}

	guint i, j;
	int rc;
	struct gridd_client_s *last, **plast;
	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;

retry:
	/* Wait for an event to happen */
	rc = metautils_syscall_poll (pfd, j, 100);
	if (rc == 0) {
		_clients_expire(clients, oio_ext_monotonic_time ());
		return NULL;
	}
	if (rc < 0) {
		if (errno == EINTR) goto retry;
		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 */
	_clients_expire(clients, oio_ext_monotonic_time ());
	return NULL;
}