static int fdw_poll_add_fd(int idx, t_fdwatch_type rw)
{
    static int ridx;

//    eventlog(eventlog_level_trace, __FUNCTION__, "called fd: %d rw: %d", fd, rw);
    if (_ridx[idx] < 0) {
	ridx = nofds++;
	fds[ridx].fd = fdw_fd(fdw_fds + idx);
	_ridx[idx] = ridx;
	_rridx[ridx] = idx;
//	eventlog(eventlog_level_trace, __FUNCTION__, "adding new_ fd on %d", ridx);
    } else {
	if (fds[_ridx[idx]].fd != fdw_fd(fdw_fds + idx)) {
	    eventlog(eventlog_level_error,__FUNCTION__,"BUG: found existent poll_fd entry for same idx with different fd");
	    return -1;
	}
	ridx = _ridx[idx];
//	eventlog(eventlog_level_trace, __FUNCTION__, "updating fd on %d", ridx);
    }

    fds[ridx].events = 0;
    if (rw & fdwatch_type_read) fds[ridx].events |= POLLIN;
    if (rw & fdwatch_type_write) fds[ridx].events |= POLLOUT;

    return 0;
}
Exemple #2
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 #3
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;
	}
Exemple #4
0
static int fdw_select_del_fd(int idx)
{
    int fd;

    fd = fdw_fd(fdw_fds + idx);
//    eventlog(eventlog_level_trace, __FUNCTION__, "called fd: %d", fd);
    if (sr > 0) 
	eventlog(eventlog_level_error, __FUNCTION__, "BUG: called while still handling sockets");
    PSOCK_FD_CLR(fd, trfds);
    PSOCK_FD_CLR(fd, twfds);

    return 0;
}
Exemple #5
0
static int fdw_select_add_fd(int idx, t_fdwatch_type rw)
{
    int fd;

//    eventlog(eventlog_level_trace, __FUNCTION__, "called fd: %d rw: %d", fd, rw);
    fd = fdw_fd(fdw_fds + idx);

    /* select() interface is limited by FD_SETSIZE max socket value */
    if (fd >= FD_SETSIZE) return -1;

    if (rw & fdwatch_type_read) PSOCK_FD_SET(fd, trfds);
    else PSOCK_FD_CLR(fd, trfds);
    if (rw & fdwatch_type_write) PSOCK_FD_SET(fd, twfds);
    else PSOCK_FD_CLR(fd, twfds);
    if (smaxfd < fd) smaxfd = fd;

    return 0;
}
Exemple #6
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 #7
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 #8
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 #9
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 #10
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;
}