Beispiel #1
0
struct gridd_client_pool_s *
gridd_client_pool_create(void)
{
	int fdmon, fd[2];
	struct gridd_client_pool_s *pool;

	if (0 != pipe(fd)) {
		GRID_WARN("pipe() error: (%d) %s", errno, strerror(errno));
		metautils_pclose(&(fd[0]));
		metautils_pclose(&(fd[1]));
		return NULL;
	}

	if (0 > (fdmon = epoll_create(64))) {
		GRID_WARN("epoll_create error: (%d) %s", errno, strerror(errno));
		metautils_pclose(&(fd[0]));
		metautils_pclose(&(fd[1]));
		return NULL;
	}

	// TODO FIXME factorize this in metautils
	struct rlimit limit;
	memset(&limit, 0, sizeof(limit));
	if (0 != getrlimit(RLIMIT_NOFILE, &limit))
		limit.rlim_cur = limit.rlim_max = 32768;

	pool = g_malloc0(sizeof(*pool));
	pool->pending_clients = g_async_queue_new();

	pool->fdmon = fdmon;
	pool->active_max = limit.rlim_cur;
	pool->active_clients_size = limit.rlim_cur;
	pool->active_clients = g_malloc0(pool->active_clients_size
			* sizeof(struct event_client_s*));

	pool->fd_in = fd[0];
	fd[0] = -1;
	metautils_syscall_shutdown(pool->fd_in, SHUT_WR);
	sock_set_non_blocking(pool->fd_in, TRUE);

	pool->fd_out = fd[1];
	fd[1] = -1;
	metautils_syscall_shutdown(pool->fd_out, SHUT_RD);
	sock_set_non_blocking(pool->fd_out, TRUE);

	/* then monitors at least the notifications pipe's output */
	struct epoll_event ev;
	memset(&ev, 0, sizeof(ev));
	ev.events = EPOLLIN;
	ev.data.fd = pool->fd_in;
	if (0 > epoll_ctl(pool->fdmon, EPOLL_CTL_ADD, pool->fd_in, &ev)) {
		GRID_ERROR("epoll error: (%d) %s", errno, strerror(errno));
		gridd_client_pool_destroy(pool);
		return NULL;
	}

	pool->vtable = &VTABLE;
	return pool;
}
Beispiel #2
0
inline
bool sock_set_non_blocking(int sock, int is_non_blocking)
{
    udp_sock s(sock);

    return sock_set_non_blocking(s, is_non_blocking);
}
Beispiel #3
0
int
accept_nonblock(int srv, struct sockaddr *sa, socklen_t *sa_len)
{
	if (VTABLE.accept_nonblock)
		return VTABLE.accept_nonblock(srv, sa, sa_len);
#ifdef HAVE_ACCEPT4
	return metautils_syscall_accept4(srv, sa, sa_len, SOCK_NONBLOCK);
#else
	int fd = metautils_syscall_accept(srv, sa, sa_len);
	if (fd >= 0)
		sock_set_non_blocking(fd, TRUE);
	return fd;
#endif
}
Beispiel #4
0
int
socket_nonblock(int domain, int type, int protocol)
{
	if (VTABLE.socket_nonblock)
		return VTABLE.socket_nonblock(domain, type, protocol);
#ifdef HAVE_SOCKET3
	return metautils_syscall_socket(domain, type|SOCK_NONBLOCK, protocol);
#else
	int fd = metautils_syscall_socket(domain, type, protocol);
	if (fd < 0)
		return fd;
	if (sock_set_non_blocking(fd, TRUE))
		return fd;
	metautils_pclose(&fd);
	return -1;
#endif
}
Beispiel #5
0
static GError *
_endpoint_open(struct endpoint_s *u)
{
	EXTRA_ASSERT(u != NULL);

	struct sockaddr_storage ss;
	socklen_t ss_len = sizeof(ss);
	memset(&ss, 0, sizeof(ss));

	/* patch some socket preferences that make sense only for INET sockets */
	if (_endpoint_is_UNIX(u)) {
		u->port_real = 0;
		u->port_cfg = 0;
		u->flags &= ~(NETSERVER_THROUGHPUT|NETSERVER_LATENCY);
	}

	/* Get a socket of the right type */
	if (_endpoint_is_UNIX(u))
		u->fd = socket(AF_UNIX, SOCK_STREAM, 0);
	else if (_endpoint_is_INET6(u))
		u->fd = socket(AF_INET6, SOCK_STREAM, 0);
	else
		u->fd = socket(AF_INET, SOCK_STREAM, 0);
	if (u->fd < 0)
		return NEWERROR(errno, "socket() = '%s'", strerror(errno));

	if (_endpoint_is_INET(u))
		sock_set_reuseaddr (u->fd, TRUE);

	/* Bind the socket the right way according to its type */
	if (_endpoint_is_UNIX(u)) {
		struct sockaddr_un *sun = (struct sockaddr_un*) &ss;
		ss_len = sizeof(*sun);
		sun->sun_family = AF_UNIX;
		g_strlcpy(sun->sun_path, u->url, sizeof(sun->sun_path));
	} else if (_endpoint_is_INET6(u)) {
		struct sockaddr_in6 *s6 = (struct sockaddr_in6*) &ss;
		ss_len = sizeof(*s6);
		s6->sin6_family = AF_INET6;
		s6->sin6_port = htons(u->port_cfg);
		inet_pton(AF_INET6, u->url, &(s6->sin6_addr));
	} else {
		struct sockaddr_in *s4 = (struct sockaddr_in*) &ss;
		ss_len = sizeof(*s4);
		s4->sin_family = AF_INET;
		s4->sin_port = htons(u->port_cfg);
		inet_pton(AF_INET, u->url, &(s4->sin_addr));
	}
	if (0 > bind(u->fd, (struct sockaddr*)&ss, ss_len)) {
		int errsave = errno;
		u->port_real = 0;
		if (_endpoint_is_UNIX(u))
			metautils_pclose (&u->fd);
		return NEWERROR(errsave, "bind(%s) = '%s'", u->url, strerror(errsave));
	}

	/* for INET sockets, get the port really used */
	if (_endpoint_is_INET(u)) {
		memset(&ss, 0, sizeof(ss));
		ss_len = sizeof(ss);
		getsockname(u->fd, (struct sockaddr*)&ss, &ss_len);
		if (_endpoint_is_INET4(u))
			u->port_real = ntohs(((struct sockaddr_in*)&ss)->sin_port);
		else
			u->port_real = ntohs(((struct sockaddr_in6*)&ss)->sin6_port);
	}

	/* And finally set the mandatory fags. */
	sock_set_non_blocking(u->fd, TRUE);

	if (0 > listen(u->fd, 32768))
		return NEWERROR(errno, "listen() = '%s'", strerror(errno));

	return NULL;
}