Example #1
0
static ret_t
_add (cherokee_fdpoll_select_t *fdp, int fd, int rw)
{
	cherokee_fdpoll_t *nfd = FDPOLL(fdp);

	/* Check the fd limit
	 */
	if (cherokee_fdpoll_is_full(FDPOLL(fdp))) {
		PRINT_ERROR_S("win32_add: fdpoll is full !\n");
		return ret_error;
	}

	fdp->select_fds[nfd->npollfds] = fd;
	switch (rw) {
		case FDPOLL_MODE_READ:
			FD_SET (fd, &fdp->master_rfdset);
			break;
		case FDPOLL_MODE_WRITE:
			FD_SET (fd, &fdp->master_wfdset);
			break;
		default:
			break;
	}

	if (fd > fdp->maxfd) {
		fdp->maxfd = fd;
	}

	nfd->npollfds++;
	return ret_ok;
}
Example #2
0
static ret_t
_del (cherokee_fdpoll_epoll_t *fdp, int fd)
{
	struct epoll_event ev;

	ev.events   = 0;
	ev.data.u64 = 0;  /* <- I just wanna be sure there aren't */
	ev.data.fd  = fd; /* <- 4 bytes uninitialized */

	/* Check the fd limit
	 */
	if (unlikely (cherokee_fdpoll_is_empty (FDPOLL(fdp)))) {
		SHOULDNT_HAPPEN;
		return ret_error;
	}

	if (epoll_ctl(fdp->ep_fd, EPOLL_CTL_DEL, fd, &ev) < 0) {
		LOG_ERRNO (errno, cherokee_err_error,
			   CHEROKEE_ERROR_FDPOLL_EPOLL_CTL_DEL, fdp->ep_fd, fd);
		return ret_error;
	}

	FDPOLL(fdp)->npollfds--;
	return ret_ok;
}
Example #3
0
static ret_t
_del (cherokee_fdpoll_select_t *fdp, int fd)
{
	cherokee_fdpoll_t *nfd = FDPOLL(fdp);
	int                idx = fdp->select_fdidx[fd];

	if ((idx < 0) || (idx >= FDPOLL(fdp)->nfiles)) {
		PRINT_ERROR ("Bad idx (%d) in select_del_fd!\n", idx);
		return ret_error;
	}

	nfd->npollfds--;
	fdp->select_fds[idx]                    = fdp->select_fds[nfd->npollfds];
	fdp->select_fdidx[fdp->select_fds[idx]] = idx;
	fdp->select_fds[nfd->npollfds]          = -1;
	fdp->select_fdidx[fd]                   = -1;
	fdp->fd_rw[fd]                          = -1;

	FD_CLR (fd, &fdp->master_rfdset);
	FD_CLR (fd, &fdp->master_wfdset);

	if (fd >= fdp->maxfd) {
		fdp->maxfd_recompute = 1;
	}

	return ret_ok;
}
Example #4
0
static int
_watch (cherokee_fdpoll_port_t *fdp, int timeout_msecs)
{
	int          i, rc, fd;
	struct timespec  timeout;

	timeout.tv_sec  = timeout_msecs/1000L;
	timeout.tv_nsec = ( timeout_msecs % 1000L ) * 1000000L;

	for (i=0; i<FDPOLL(fdp)->system_nfiles; i++) {
		fdp->port_activefd[i] = -1;
	}

	/* First call to get the number of file descriptors with activity
	 */
	rc = port_getn (fdp->port, fdp->port_events, 0,
			(uint_t *)&fdp->port_readyfds,
		        &timeout);
	if ( rc < 0 ) {
		LOG_ERRNO_S (errno, cherokee_err_error, CHEROKEE_ERROR_FDPOLL_PORTS_GETN);
		return 0;
	}

	if ( fdp->port_readyfds == 0 ) {
		/* Get at least 1 fd to wait for activity
		 */
		fdp->port_readyfds = 1;
	}

	/* Second call to get the events of the file descriptors with
	 * activity
	 */
	rc = port_getn (fdp->port, fdp->port_events,FDPOLL(fdp)->nfiles,
			&fdp->port_readyfds, &timeout);
	if ( ( (rc < 0) && (errno != ETIME) ) || (fdp->port_readyfds == -1)) {
		LOG_ERRNO_S (errno, cherokee_err_error, CHEROKEE_ERROR_FDPOLL_PORTS_GETN);
		return 0;
	}

	for ( i = 0; i < fdp->port_readyfds; ++i ) {
		int nfd;

		nfd = fdp->port_events[i].portev_object;
		fdp->port_activefd[nfd] = fdp->port_events[i].portev_events;
		rc = fd_associate( fdp,
		                   nfd,
		                   fdp->port_events[i].portev_user);
		if ( rc < 0 ) {
			LOG_ERRNO (errno, cherokee_err_error,
				   CHEROKEE_ERROR_FDPOLL_PORTS_FD_ASSOCIATE, nfd);
		}
	}

	return fdp->port_readyfds;
}
Example #5
0
static int
_watch (cherokee_fdpoll_kqueue_t *fdp, int timeout_msecs)
{
	struct timespec  timeout;
	int              i;
	int              n_events;

	timeout.tv_sec  = timeout_msecs/1000L;
	timeout.tv_nsec = ( timeout_msecs % 1000L ) * 1000000L;

	/* Get the events of the file descriptors with
	 * activity
	 */
again:
	n_events = kevent (fdp->kqueue,
	                   fdp->changelist,
	                   fdp->nchanges,
	                   fdp->changelist,
	                   FDPOLL(fdp)->nfiles,
	                   &timeout);

	fdp->nchanges = 0;

	if (unlikely (n_events < 0)) {
		if (errno == EINTR)
			goto again;

		LOG_ERRNO (errno, cherokee_err_error, CHEROKEE_ERROR_FDPOLL_KQUEUE);
		return 0;

	} else if (n_events > 0) {
		memset (fdp->fdevents, 0, FDPOLL(fdp)->system_nfiles * sizeof(int));

		for (i = 0; i < n_events; ++i) {
			/* Filter */
			if (fdp->changelist[i].filter == EVFILT_READ) {
				fdp->fdevents[fdp->changelist[i].ident] = KQUEUE_READ_EVENT;
			} else if (fdp->changelist[i].filter == EVFILT_WRITE) {
				fdp->fdevents[fdp->changelist[i].ident] = KQUEUE_WRITE_EVENT;
			} else {
				SHOULDNT_HAPPEN;
			}

			/* Flags */
			if (fdp->changelist[i].flags & (EV_EOF | EV_ERROR)) {
				fdp->fdevents[fdp->changelist[i].ident] = KQUEUE_CLOSE;
			}
		}
	}

	return n_events;
}
Example #6
0
static ret_t
_del (cherokee_fdpoll_select_t *fdp, int fd)
{
	cherokee_fdpoll_t *nfd = FDPOLL(fdp);
	int                i;

	for (i=0; i < nfd->npollfds; i++) {
		if (fdp->select_fds[i] != fd)
			continue;

		nfd->npollfds--;
		fdp->select_fds[i]             = fdp->select_fds[nfd->npollfds];
		fdp->select_fds[nfd->npollfds] = -1;

		FD_CLR (fd, &fdp->master_rfdset);
		FD_CLR (fd, &fdp->master_wfdset);

		if (fd >= fdp->maxfd) {
			fdp->maxfd_recompute = 1;
		}

		return ret_ok;
	}

	PRINT_ERROR ("Couldn't remove fd %d\n", fd);
	return ret_error;
}
Example #7
0
static int
_watch (cherokee_fdpoll_select_t *fdp, int timeout_msecs)
{
	int mfd;
	int r, idx, ridx;

	fdp->working_rfdset = fdp->master_rfdset;
	fdp->working_wfdset = fdp->master_wfdset;
	mfd = select_get_maxfd(fdp);
	if (timeout_msecs == INFTIM) {
		r = select (mfd + 1, &fdp->working_rfdset, &fdp->working_wfdset, NULL, NULL);
	} else {
		struct timeval timeout;
		timeout.tv_sec = timeout_msecs / 1000L;
		timeout.tv_usec = ( timeout_msecs % 1000L ) * 1000L;
		r = select (mfd + 1, &fdp->working_rfdset, &fdp->working_wfdset, NULL, &timeout);
	}

	if (r <= 0) {
		return r;
	}

	ridx = 0;
	for (idx = 0; idx < FDPOLL(fdp)->npollfds; ++idx) {
		if (_check (fdp, fdp->select_fds[idx], 0)) {
			fdp->select_rfdidx[ridx++] = fdp->select_fds[idx];
			if (ridx == r)
				break;
		}
	}

	return ridx;        /* should be equal to r */
}
Example #8
0
static ret_t
_add_change(cherokee_fdpoll_kqueue_t *fdp, int fd, int rw, int change )
{
	int            index;
	struct kevent *event;

	index = fdp->nchanges;
	if (unlikely (index >= FDPOLL(fdp)->nfiles)) {
		PRINT_ERROR_S("kqueue_add: fdpoll is full !\n");
		return ret_error;
	}

	event = &fdp->changelist[index];
	event->ident = fd;
	switch (rw) {
	case FDPOLL_MODE_READ:
		event->filter = EVFILT_READ;
		break;
	case FDPOLL_MODE_WRITE:
		event->filter = EVFILT_WRITE;
		break;
	default:
		SHOULDNT_HAPPEN;
	}

	event->flags  = change;
	event->fflags = 0;

	fdp->fdinterest[fd] = rw;
	fdp->nchanges++;

	return ret_ok;
}
Example #9
0
ret_t
fdpoll_kqueue_new (cherokee_fdpoll_t **fdp, int sys_fd_limit, int fd_limit)
{
	int                re;
	cherokee_fdpoll_t *nfd;

	CHEROKEE_CNEW_STRUCT (1, n, fdpoll_kqueue);

	nfd = FDPOLL(n);

	/* Init base class properties
	 */
	nfd->type          = cherokee_poll_kqueue;
	nfd->nfiles        = fd_limit;
	nfd->system_nfiles = sys_fd_limit;
	nfd->npollfds      = 0;

	/* Init base class virtual methods
	 */
	nfd->free          = (fdpoll_func_free_t) _free;
	nfd->add           = (fdpoll_func_add_t) _add;
	nfd->del           = (fdpoll_func_del_t) _del;
	nfd->reset         = (fdpoll_func_reset_t) _reset;
	nfd->set_mode      = (fdpoll_func_set_mode_t) _set_mode;
	nfd->check         = (fdpoll_func_check_t) _check;
	nfd->watch         = (fdpoll_func_watch_t) _watch;

	/* Init kqueue specific variables
	 */
	n->kqueue          = -1;
	n->nchanges        = 0;
	n->changelist      = (struct kevent *) calloc (nfd->nfiles * 2, sizeof(struct kevent));
	n->fdevents        = (int *) calloc (nfd->system_nfiles, sizeof(int));
	n->fdinterest      = (int *) calloc (nfd->system_nfiles, sizeof(int));

	if (n->fdevents == NULL || n->changelist == NULL || n->fdinterest == NULL) {
		_free (n);
		return ret_nomem;
	}

	n->kqueue = kqueue();
	if (n->kqueue == -1) {
		_free (n);
		return ret_error;
	}

	re = fcntl (n->kqueue, F_SETFD, FD_CLOEXEC);
	if (re < 0) {
		LOG_ERRNO (errno, cherokee_err_error,
			   CHEROKEE_ERROR_FDPOLL_EPOLL_CLOEXEC);
		_free (n);
		return ret_error;
	}

	/* Return the object
	 */
	*fdp = nfd;
	return ret_ok;
}
Example #10
0
static int
_check (cherokee_fdpoll_epoll_t *fdp, int fd, int rw)
{
	int      fdidx;
	uint32_t events;

	/* Sanity check: is it a wrong fd?
	 */
	if (fd < 0 || fd >= FDPOLL(fdp)->system_nfiles)
		return -1;

	/* If fdidx is -1, it is not valid, ignore it.
	 */
	fdidx = fdp->epoll_fd2idx[fd];
	if (fdidx < 0 || fdidx >= fdp->ep_nrevents)
		return 0;

	/* Sanity check
	 */
	if (fdidx >= FDPOLL(fdp)->nfiles) {
		PRINT_ERROR ("ERROR: fdpoll: out of range, %d of %d, fd=%d\n",
			     fdidx, FDPOLL(fdp)->nfiles, fd);
		return -1;
	}

	/* Sanity check
	 */
	if (fdp->ep_events[fdidx].data.fd != fd)
		return 0;
	/*	return -1; */

	/* Check for errors
	 */
	events = fdp->ep_events[fdidx].events;

	switch (rw) {
	case FDPOLL_MODE_READ:
		return events & (EPOLLIN  | EPOLLERR | EPOLLHUP);
	case FDPOLL_MODE_WRITE:
		return events & (EPOLLOUT | EPOLLERR | EPOLLHUP);
	default:
		return -1;
	}
}
Example #11
0
ret_t
fdpoll_win32_new (cherokee_fdpoll_t **fdp, int system_fd_limit, int fd_limit)
{
	int                i;
	cherokee_fdpoll_t *nfd;
	CHEROKEE_CNEW_STRUCT (1, n, fdpoll_select);

	/* Verify that the max. number of selectable fds
	 * is below the max. acceptable limit per select set.
	 */
	if (fd_limit > FD_SETSIZE) {
		_free(n);
		return ret_error;
	}

	nfd = FDPOLL(n);

	/* Init base class properties
	 */
	nfd->type          = cherokee_poll_win32;
	nfd->nfiles        = fd_limit;
	nfd->system_nfiles = system_fd_limit;
	nfd->npollfds      =  0;

	/* Init base class virtual methods
	 */
	nfd->free          = (fdpoll_func_free_t) _free;
	nfd->add           = (fdpoll_func_add_t) _add;
	nfd->del           = (fdpoll_func_del_t) _del;
	nfd->reset         = (fdpoll_func_reset_t) _reset;
	nfd->set_mode      = (fdpoll_func_set_mode_t) _set_mode;
	nfd->check         = (fdpoll_func_check_t) _check;
	nfd->watch         = (fdpoll_func_watch_t) _watch;

	/* Init properties
	 */
	FD_ZERO (&n->master_rfdset);
	FD_ZERO (&n->master_wfdset);

	n->select_fds      = (int*) calloc(nfd->nfiles, sizeof(int));
	n->maxfd           = -1;
	n->maxfd_recompute =  0;

	if (n->select_fds == NULL) {
		_free (n);
		return ret_nomem;
	}

	for (i = 0; i < nfd->nfiles; ++i) {
		n->select_fds[i] = -1;
	}

	*fdp = nfd;
	return ret_ok;
}
Example #12
0
static ret_t
_reset (cherokee_fdpoll_epoll_t *fdp, int fd)
{
	/* Sanity check: is it a wrong fd?
	 */
	if (fd < 0 || fd >= FDPOLL(fdp)->system_nfiles)
		return ret_error;

	fdp->epoll_fd2idx[fd] = -1;

	return ret_ok;
}
Example #13
0
static ret_t
_add (cherokee_fdpoll_kqueue_t *fdp, int fd, int rw)
{
	int re;

	re = _add_change (fdp, fd, rw, EV_ADD);
	if (re == ret_ok) {
		FDPOLL(fdp)->npollfds++;
	}

	return re;
}
Example #14
0
static ret_t
_del (cherokee_fdpoll_kqueue_t *fdp, int fd)
{
	int re;

	re = _add_change (fdp, fd, fdp->fdinterest[fd], EV_DELETE);
	if (re == ret_ok) {
		FDPOLL(fdp)->npollfds--;
	}

	return re;
}
Example #15
0
ret_t
fdpoll_port_new (cherokee_fdpoll_t **fdp, int sys_limit, int limit)
{
	cuint_t            i;
	cherokee_fdpoll_t *nfd;
	CHEROKEE_CNEW_STRUCT (1, n, fdpoll_port);

	nfd = FDPOLL(n);

	/* Init base class properties
	 */
	nfd->type          = cherokee_poll_port;
	nfd->nfiles        = limit;
	nfd->system_nfiles = sys_limit;
	nfd->npollfds      = 0;

	/* Init base class virtual methods
	 */
	nfd->free          = (fdpoll_func_free_t) _free;
	nfd->add           = (fdpoll_func_add_t) _add;
	nfd->del           = (fdpoll_func_del_t) _del;
	nfd->reset         = (fdpoll_func_reset_t) _reset;
	nfd->set_mode      = (fdpoll_func_set_mode_t) _set_mode;
	nfd->check         = (fdpoll_func_check_t) _check;
	nfd->watch         = (fdpoll_func_watch_t) _watch;

	/* Allocate data
	 */
	n->port = -1;
	n->port_readyfds = 0;
	n->port_events   = (port_event_t *) calloc(nfd->nfiles, sizeof(port_event_t));
	n->port_activefd = (int *) calloc(nfd->system_nfiles, sizeof(int));

	if ( n->port_events == NULL || n->port_activefd == NULL ) {
		_free( n );
		return ret_nomem;
	}

	for (i=0; i < nfd->system_nfiles; i++) {
		n->port_activefd[i] = -1;
	}

	if ( (n->port = port_create()) == -1 ) {
		_free( n );
		return ret_error;
	}

	/* Return the object
	 */
	*fdp = nfd;
	return ret_ok;
}
Example #16
0
static ret_t
_add (cherokee_fdpoll_epoll_t *fdp, int fd, int rw)
{
	struct epoll_event ev;

	/* Check the fd limit
	 */
	if (unlikely (cherokee_fdpoll_is_full (FDPOLL(fdp)))) {
		PRINT_ERROR_S("epoll_add: fdpoll is full !\n");
		return ret_error;
	}

	/* Add the new descriptor
	 */
	ev.data.u64 = 0;
	ev.data.fd = fd;
	switch (rw) {
	case FDPOLL_MODE_READ:
		ev.events = EPOLLIN | EPOLLERR | EPOLLHUP;
		break;
	case FDPOLL_MODE_WRITE:
		ev.events = EPOLLOUT | EPOLLERR | EPOLLHUP;
		break;
	default:
		ev.events = 0;
		SHOULDNT_HAPPEN;
		return ret_error;
	}

	if (epoll_ctl (fdp->ep_fd, EPOLL_CTL_ADD, fd, &ev) < 0) {
		LOG_ERRNO (errno, cherokee_err_error,
			   CHEROKEE_ERROR_FDPOLL_EPOLL_CTL_ADD, fdp->ep_fd, fd);
		return ret_error;
	}

	FDPOLL(fdp)->npollfds++;
	return ret_ok;
}
Example #17
0
static ret_t
_add (cherokee_fdpoll_port_t *fdp, int fd, int rw)
{
	int rc;

	rc = fd_associate(fdp, fd, (rw == FDPOLL_MODE_WRITE ? WRITE : READ));
	if ( rc == -1 ) {
		LOG_ERRNO (errno, cherokee_err_error,
			   CHEROKEE_ERROR_FDPOLL_PORTS_FD_ASSOCIATE, fd);
		return ret_error;
	}

	FDPOLL(fdp)->npollfds++;
	return ret_ok;
}
Example #18
0
static int
_watch (cherokee_fdpoll_epoll_t *fdp, int timeout_msecs)
{
	int i;

	fdp->ep_nrevents = epoll_wait (fdp->ep_fd, fdp->ep_events, FDPOLL(fdp)->nfiles, timeout_msecs);
	if (fdp->ep_nrevents < 1)
		return fdp->ep_nrevents;

	for (i = 0; i < fdp->ep_nrevents; ++i) {
		fdp->epoll_fd2idx[fdp->ep_events[i].data.fd] = i;
	}

	return fdp->ep_nrevents;
}
Example #19
0
static int
select_get_maxfd (cherokee_fdpoll_select_t *fdp)
{
	if (fdp->maxfd_recompute) {
		int i;

		fdp->maxfd = -1;
		for (i = 0; i < FDPOLL(fdp)->npollfds; ++i) {
			if (fdp->select_fds[i] > fdp->maxfd ) {
				fdp->maxfd = fdp->select_fds[i];
			}
		}

		fdp->maxfd_recompute = 0;
	}

	return fdp->maxfd;
}
Example #20
0
static ret_t
_del (cherokee_fdpoll_port_t *fdp, int fd)
{
	int rc;

	rc = port_dissociate( fdp->port,      /* port */
	                      PORT_SOURCE_FD, /* source */
	                      fd);            /* object */
	if ( rc == -1 ) {
		LOG_ERRNO (errno, cherokee_err_error,
			   CHEROKEE_ERROR_FDPOLL_PORTS_ASSOCIATE, fd);
		return ret_error;
	}

	FDPOLL(fdp)->npollfds--;

	/* remote fd from the active fd list
	 */
	fdp->port_activefd[fd] = -1;

	return ret_ok;
}
Example #21
0
ret_t
fdpoll_epoll_new (cherokee_fdpoll_t **fdp, int sys_fd_limit, int fd_limit)
{
	int                re;
	cherokee_fdpoll_t *nfd;
	CHEROKEE_CNEW_STRUCT (1, n, fdpoll_epoll);

	nfd = FDPOLL(n);

	/* Init base class properties
	 */
	nfd->type          = cherokee_poll_epoll;
	nfd->nfiles        = fd_limit;
	nfd->system_nfiles = sys_fd_limit;
	nfd->npollfds      = 0;

	/* Init base class virtual methods
	 */
	nfd->free          = (fdpoll_func_free_t) _free;
	nfd->add           = (fdpoll_func_add_t) _add;
	nfd->del           = (fdpoll_func_del_t) _del;
	nfd->reset         = (fdpoll_func_reset_t) _reset;
	nfd->set_mode      = (fdpoll_func_set_mode_t) _set_mode;
	nfd->check         = (fdpoll_func_check_t) _check;
	nfd->watch         = (fdpoll_func_watch_t) _watch;

	/* Look for max fd limit
	 */
	n->ep_fd = -1;
	n->ep_nrevents  = 0;
	n->ep_events    = (struct epoll_event *) calloc (nfd->nfiles, sizeof(struct epoll_event));
	n->epoll_fd2idx = (int *) calloc (nfd->system_nfiles, sizeof(int));

	/* If anyone fails free all and return ret_nomem
	 */
	if (n->ep_events == NULL || n->epoll_fd2idx == NULL) {
		_free(n);
		return ret_nomem;
	}

	for (re = 0; re < nfd->system_nfiles; re++) {
		n->epoll_fd2idx[re] = -1;
	}

	n->ep_fd = epoll_create (nfd->nfiles);
	if (n->ep_fd < 0) {
		/* It may fail here if the glibc library supports epoll,
		 * but the kernel doesn't.
		 */
#if 0
		LOG_ERRNO (errno, cherokee_err_error,
			   CHEROKEE_ERROR_FDPOLL_EPOLL_CREATE, nfd->nfiles+1);
#endif
		_free (n);
		return ret_error;
	}

	re = fcntl (n->ep_fd, F_SETFD, FD_CLOEXEC);
	if (re < 0) {
		LOG_ERRNO (errno, cherokee_err_error,
			   CHEROKEE_ERROR_FDPOLL_EPOLL_CLOEXEC);
		_free (n);
		return ret_error;
	}

	/* Return the object
	 */
	*fdp = nfd;
	return ret_ok;
}