Exemple #1
0
	extern int fdwatch_del_fd(int idx)
	{
		if (idx < 0 || idx >= fdw_maxcons) {
			ERROR2("out of bounds idx [{}] (max: {})", idx, fdw_maxcons);
			return -1;
		}

		t_fdwatch_fd *cfd = fdw_fds + idx;
		if (!fdw_rw(cfd)) {
			ERROR0("found reseted rw");
			return -1;
		}

		fdw->del(idx);

		/* remove it from uselist, add it to freelist */
		uselist.remove(*cfd);
		freelist.push_back(*cfd);

		fdw_fd(cfd) = 0;
		fdw_rw(cfd) = 0;
		fdw_data(cfd) = NULL;
		fdw_hnd(cfd) = NULL;

		return 0;
	}
static void fdw_poll_handle(void)
{
    register unsigned i;
    int changed;
    t_fdwatch_fd *cfd;

    for(i = 0; i < nofds && sr; i++) {
	changed = 0;
	cfd = fdw_fds + _rridx[i];

	if (fdw_rw(cfd) & fdwatch_type_read && 
	    fds[i].revents & (POLLIN  | POLLERR | POLLHUP | POLLNVAL))
	{
	    if (fdw_hnd(cfd)(fdw_data(cfd), fdwatch_type_read) == -2) {
		sr--;
		continue;
	    }
	    changed = 1;
	}

	if (fdw_rw(cfd) & fdwatch_type_write && 
	    fds[i].revents & (POLLOUT  | POLLERR | POLLHUP | POLLNVAL))
	{
	    fdw_hnd(cfd)(fdw_data(cfd), fdwatch_type_write);
	    changed = 1;
	}

	if (changed) sr--;
    }
}
Exemple #3
0
static int fdw_select_cb(t_fdwatch_fd *cfd, void *data)
{
//    eventlog(eventlog_level_trace, __FUNCTION__, "idx: %d fd: %d", idx, fdw_fd->fd);
    if (fdw_rw(cfd) & fdwatch_type_read && PSOCK_FD_ISSET(fdw_fd(cfd), rfds)
        && fdw_hnd(cfd)(fdw_data(cfd), fdwatch_type_read) == -2) return 0;
    if (fdw_rw(cfd) & fdwatch_type_write && PSOCK_FD_ISSET(fdw_fd(cfd), wfds))
        fdw_hnd(cfd)(fdw_data(cfd), fdwatch_type_write);

    return 0;
}
Exemple #4
0
void
FDWKqueueBackend::handle()
{
/*    eventlog(eventlog_level_trace, __FUNCTION__, "called"); */
	for (unsigned i = 0; i < sr; i++)
	{
/*      eventlog(eventlog_level_trace, __FUNCTION__, "checking %d ident: %d read: %d write: %d", i, kqevents[i].ident, kqevents[i].filter & EVFILT_READ, kqevents[i].filter & EVFILT_WRITE); */
		t_fdwatch_fd *cfd = fdw_fds + (unsigned long)kqevents[i].udata;
		if (fdw_rw(cfd) & fdwatch_type_read && kqevents[i].filter == EVFILT_READ)
			if (fdw_hnd(cfd) (fdw_data(cfd), fdwatch_type_read) == -2)
				continue;

		if (fdw_rw(cfd) & fdwatch_type_write && kqevents[i].filter == EVFILT_WRITE)
			fdw_hnd(cfd) (fdw_data(cfd), fdwatch_type_write);
	}
	sr = 0;
}
Exemple #5
0
void
FDWEpollBackend::handle()
{
//    eventlog(eventlog_level_trace, __FUNCTION__, "called");
	for (struct epoll_event *ev = epevents.get(); sr; sr--, ev++)
	{
//      eventlog(eventlog_level_trace, __FUNCTION__, "checking %d ident: %d read: %d write: %d", i, kqevents[i].ident, kqevents[i].filter & EVFILT_READ, kqevents[i].filter & EVFILT_WRITE);
		t_fdwatch_fd *cfd = fdw_fds + ev->data.fd;

		if (fdw_rw(cfd) & fdwatch_type_read && ev->events & (EPOLLIN | EPOLLERR | EPOLLHUP))
		if (fdw_hnd(cfd) (fdw_data(cfd), fdwatch_type_read) == -2)
			continue;

		if (fdw_rw(cfd) & fdwatch_type_write && ev->events & (EPOLLOUT | EPOLLERR | EPOLLHUP))
			fdw_hnd(cfd) (fdw_data(cfd), fdwatch_type_write);
	}
	sr = 0;
}
Exemple #6
0
	extern int fdwatch_update_fd(int idx, unsigned rw)
	{
		if (idx < 0 || idx >= fdw_maxcons) {
			ERROR2("out of bounds idx [{}] (max: {})", idx, fdw_maxcons);
			return -1;
		}
		/* do not allow completly reset the access because then backend codes
		 * can get confused */
		if (!rw) {
			ERROR0("tried to reset rw, not allowed");
			return -1;
		}

		if (!fdw_rw(fdw_fds + idx)) {
			ERROR0("found reseted rw");
			return -1;
		}

		if (fdw->add(idx, rw)) return -1;
		fdw_rw(&fdw_fds[idx]) = rw;

		return 0;
	}
Exemple #7
0
int
FDWEpollBackend::del(int idx)
{
//    eventlog(eventlog_level_trace, __FUNCTION__, "called fd: %d", fd);
	if (sr > 0)
		ERROR0("BUG: called while still handling sockets");

	if (fdw_rw(fdw_fds + idx)) {
		struct epoll_event tmpev;
		std::memset(&tmpev, 0, sizeof(tmpev));
		tmpev.events = 0;
		tmpev.data.fd = idx;
		if (epoll_ctl(epfd, EPOLL_CTL_DEL, fdw_fd(fdw_fds + idx), &tmpev)) {
			ERROR0("got error from epoll_ctl()");
			return -1;
		}
	}

	return 0;
}
Exemple #8
0
	extern int fdwatch_add_fd(int fd, unsigned rw, fdwatch_handler h, void *data)
	{
		/* max sockets reached */
		if (freelist.empty()) return -1;

		t_fdwatch_fd *cfd = &freelist.front();
		fdw_fd(cfd) = fd;

		if (fdw->add(fdw_idx(cfd), rw)) return -1;

		/* add it to used sockets list, remove it from free list */
		uselist.push_back(*cfd);
		freelist.remove(*cfd);

		fdw_rw(cfd) = rw;
		fdw_data(cfd) = data;
		fdw_hnd(cfd) = h;

		return fdw_idx(cfd);
	}
Exemple #9
0
int
FDWEpollBackend::add(int idx, unsigned rw)
{
//    eventlog(eventlog_level_trace, __FUNCTION__, "called fd: %d rw: %d", fd, rw);

	struct epoll_event tmpev;
	std::memset(&tmpev, 0, sizeof(tmpev));
	tmpev.events = 0;
	if (rw & fdwatch_type_read)
		tmpev.events |= EPOLLIN;
	if (rw & fdwatch_type_write)
		tmpev.events |= EPOLLOUT;

	int op = fdw_rw(fdw_fds + idx) ? EPOLL_CTL_MOD : EPOLL_CTL_ADD;

	tmpev.data.fd = idx;
	if (epoll_ctl(epfd, op, fdw_fd(fdw_fds + idx), &tmpev)) {
		ERROR0("got error from epoll_ctl()");
		return -1;
	}

	return 0;
}
Exemple #10
0
int
FDWKqueueBackend::add(int idx, unsigned rw)
{
	int idxr;
	t_fdwatch_fd *cfd = fdw_fds + idx;

/*    eventlog(eventlog_level_trace, __FUNCTION__, "called fd: %d rw: %d", fd, rw); */
	/* adding read event filter */
	if (!(fdw_rw(cfd) & fdwatch_type_read) && rw & fdwatch_type_read)
	{
		if (rridx[idx] >= 0 && rridx[idx] < nochanges && kqchanges[rridx[idx]].ident == fdw_fd(cfd))
		{
			idxr = rridx[idx];
/*	    eventlog(eventlog_level_trace, __FUNCTION__, "updating change event (read) fd on %d", ridx); */
		} else {
			idxr = nochanges++;
			rridx[idx] = idxr;
/*	    eventlog(eventlog_level_trace, __FUNCTION__, "adding new change event (read) fd on %d", ridx); */
		}
		EV_SET(kqchanges.get() + idxr, fdw_fd(cfd), EVFILT_READ, EV_ADD, 0, 0, (void*)idx);
	}
	else if (fdw_rw(cfd) & fdwatch_type_read && !( rw & fdwatch_type_read))
	{
		if (rridx[idx] >= 0 && rridx[idx] < nochanges && kqchanges[rridx[idx]].ident == fdw_fd(cfd))
		{
			idxr = rridx[idx];
/*	    eventlog(eventlog_level_trace, __FUNCTION__, "updating change event (read) fd on %d", ridx); */
		} else {
			idxr = nochanges++;
			rridx[idx] = idxr;
/*	    eventlog(eventlog_level_trace, __FUNCTION__, "adding new change event (read) fd on %d", ridx); */
		}
		EV_SET(kqchanges.get() + idxr, fdw_fd(cfd), EVFILT_READ, EV_DELETE, 0, 0, (void*)idx);
	}

	/* adding write event filter */
	if (!(fdw_rw(cfd) & fdwatch_type_write) && rw & fdwatch_type_write)
	{
		if (wridx[idx] >= 0 && wridx[idx] < nochanges && kqchanges[wridx[idx]].ident == fdw_fd(cfd))
		{
			idxr = wridx[idx];
/*	    eventlog(eventlog_level_trace, __FUNCTION__, "updating change event (write) fd on %d", ridx); */
		} else {
			idxr = nochanges++;
			wridx[idx] = idxr;
/*	    eventlog(eventlog_level_trace, __FUNCTION__, "adding new change event (write) fd on %d", ridx); */
		}
		EV_SET(kqchanges.get() + idxr, fdw_fd(cfd), EVFILT_WRITE, EV_ADD, 0, 0, (void*)idx);
	}
	else if (fdw_rw(cfd) & fdwatch_type_write && !(rw & fdwatch_type_write))
	{
		if (wridx[idx] >= 0 && wridx[idx] < nochanges && kqchanges[wridx[idx]].ident == fdw_fd(cfd))
		{
			idxr = wridx[idx];
/*	    eventlog(eventlog_level_trace, __FUNCTION__, "updating change event (write) fd on %d", ridx); */
		} else {
			idxr = nochanges++;
			wridx[idx] = idxr;
/*	    eventlog(eventlog_level_trace, __FUNCTION__, "adding new change event (write) fd on %d", ridx); */
		}
		EV_SET(kqchanges.get() + idxr, fdw_fd(cfd), EVFILT_WRITE, EV_DELETE, 0, 0, (void*)idx);
	}

	return 0;
}
Exemple #11
0
int
FDWKqueueBackend::del(int idx)
{
/*    eventlog(eventlog_level_trace, __FUNCTION__, "called fd: %d", fd); */
	if (sr > 0)
		eventlog(eventlog_level_error, __FUNCTION__, "BUG: called while still handling sockets");

	t_fdwatch_fd *cfd = fdw_fds + idx;
	/* the last event changes about this fd has not yet been sent to kernel */
	if (fdw_rw(cfd) & fdwatch_type_read &&
	    nochanges && rridx[idx] >= 0 && rridx[idx] < nochanges &&
	    kqchanges[rridx[idx]].ident == fdw_fd(cfd))
	{
		nochanges--;
		if (rridx[idx] < nochanges)
		{
			int oidx;

			oidx = (unsigned long)(kqchanges[nochanges].udata);
			if (kqchanges[nochanges].filter == EVFILT_READ &&
			    rridx[oidx] == nochanges)
			{
/*	    eventlog(eventlog_level_trace, __FUNCTION__, "not last, moving %d", kqchanges[rnfds].ident); */
				rridx[oidx] = rridx[idx];
				std::memcpy(kqchanges.get() + rridx[idx], kqchanges.get() + nochanges, sizeof(struct kevent));
			}

			if (kqchanges[nochanges].filter == EVFILT_WRITE &&
			    wridx[oidx] == nochanges)
			{
/*	    eventlog(eventlog_level_trace, __FUNCTION__, "not last, moving %d", kqchanges[rnfds].ident); */
				wridx[oidx] = rridx[idx];
				std::memcpy(kqchanges.get() + rridx[idx], kqchanges.get() + nochanges, sizeof(struct kevent));
			}
		}
		rridx[idx] = -1;
	}

	if (fdw_rw(cfd) & fdwatch_type_write &&
	    nochanges && wridx[idx] >= 0 && wridx[idx] < nochanges &&
	    kqchanges[wridx[idx]].ident == fdw_fd(cfd))
	{
		nochanges--;
		if (wridx[idx] < nochanges)
		{
			int oidx;

			oidx = (unsigned long)(kqchanges[nochanges].udata);
			if (kqchanges[nochanges].filter == EVFILT_READ &&
			    rridx[oidx] == nochanges)
			{
/*	    eventlog(eventlog_level_trace, __FUNCTION__, "not last, moving %d", kqchanges[rnfds].ident); */
				rridx[oidx] = wridx[idx];
				std::memcpy(kqchanges.get() + wridx[idx], kqchanges.get() + nochanges, sizeof(struct kevent));
			}

			if (kqchanges[nochanges].filter == EVFILT_WRITE &&
			    wridx[oidx] == nochanges)
			{
/*	    eventlog(eventlog_level_trace, __FUNCTION__, "not last, moving %d", kqchanges[rnfds].ident); */
				wridx[oidx] = wridx[idx];
				std::memcpy(kqchanges.get() + wridx[idx], kqchanges.get() + nochanges, sizeof(struct kevent));
			}
		}
		wridx[idx] = -1;
	}

/* here we presume the calling code does close() on the socket and if so
 * it is automatically removed from any kernel kqueues */

	return 0;
}