Exemplo n.º 1
0
void process_debt(int fd) {
    /* After a short write, we finally can deliver the "debt" */
    ssize_t ret;
    dpf("Selecting %d for writing because of debt %d\n", fd, fdinfo[fd].debt);
send_was_interrupted2:
    ret = send(fd, fdinfo[fd].buff, fdinfo[fd].debt, 0);
    dpf("    sent %d bytes\n", ret);
    if (ret == 0) {
	fprintf(stderr, "send returned 0? Submit to codinghorror?\n");
	close_fd(fd);
	return;
    } else
    if (ret < 0) {
	if(errno==EINTR) goto send_was_interrupted2;
	if(errno==EAGAIN) {
	    fdinfo[fd].writeready=0;			    
	    fdinfo[fd].we_should_epoll_for_writes=1;
	    epoll_update(fd);
	} else {
	    fprintf(stderr, "Why epoll hasn't told us that there would be error at sending?\n");
	    perror("send");
	    close_fd(fd);
	    return;
	}
    } else {
	if (ret < fdinfo[fd].debt) {
	    dpf("    short write at %d\n", fd);
	    /* _Again_ short write. Need to remember the rest of the buffer somewhere. */
	    int l = fdinfo[fd].debt - ret;
	    char* b = (char*)malloc(l);
	    if (b == NULL) {
		perror("malloc");
		close_fd(fd);
		return;
	    }
	    memcpy(b, fdinfo[fd].buff + ret, l);
	    free(fdinfo[fd].buff);
	    fdinfo[fd].buff = b;
	    fdinfo[fd].debt = l;
        
	    fdinfo[fd].we_should_epoll_for_writes=1;
	    epoll_update(fd);

	    dpf("    re-stored debt %d for %d\n", l, fd);
	} else {
	    /* Now the debt is fulfilled */
	    free(fdinfo[fd].buff);
	    fdinfo[fd].buff = NULL;
	    fdinfo[fd].debt = 0;
	    dpf("    debt is fulfilled for %d\n", fd);
	    /* and we can start a new cycle */
	    fdinfo[fdinfo[fd].peerfd].we_should_epoll_for_reads = 1;
	    epoll_update(fdinfo[fd].peerfd);
	}
    }
}
Exemplo n.º 2
0
int
evfilt_socket_knote_create(struct filter *filt, struct knote *kn)
{
    struct epoll_event ev;

    if (linux_get_descriptor_type(kn) < 0)
        return (-1);

    /* TODO: return EBADF? */
    if (kn->kn_flags & KNFL_REGULAR_FILE)
        return (-1);

    /* Convert the kevent into an epoll_event */
    kn->data.events = EPOLLOUT;
    if (kn->kev.flags & EV_ONESHOT || kn->kev.flags & EV_DISPATCH)
        kn->data.events |= EPOLLONESHOT;
    if (kn->kev.flags & EV_CLEAR)
        kn->data.events |= EPOLLET;

    memset(&ev, 0, sizeof(ev));
    ev.events = kn->data.events;
    ev.data.ptr = kn;

    return epoll_update(EPOLL_CTL_ADD, filt, kn, &ev);
}
Exemplo n.º 3
0
int
evfilt_read_knote_delete(struct filter *filt, struct knote *kn)
{
    if (kn->kev.flags & EV_DISABLE)
        return (0);

    if  (
            (
                   kn->kn_flags & KNFL_REGULAR_FILE
                && kn->kdata.kn_eventfd != -1
            ) == true
        ) {
        if (epoll_ctl(kn->kn_epollfd, EPOLL_CTL_DEL, kn->kdata.kn_eventfd, NULL) < 0) {
            dbg_perror("epoll_ctl(2)");
            return (-1);
        }
        (void) close(kn->kdata.kn_eventfd);
        kn->kdata.kn_eventfd = -1;
    } else {
        return epoll_update(EPOLL_CTL_DEL, filt, kn, NULL);
    }

    // clang will complain about not returning a value otherwise
    return (-1);
}
Exemplo n.º 4
0
int
evfilt_socket_knote_delete(struct filter *filt, struct knote *kn)
{
    if (kn->kev.flags & EV_DISABLE)
        return (0);
    else
        return epoll_update(EPOLL_CTL_DEL, filt, kn, NULL);
}
Exemplo n.º 5
0
int
evfilt_socket_knote_enable(struct filter *filt, struct knote *kn)
{
    struct epoll_event ev;

    memset(&ev, 0, sizeof(ev));
    ev.events = kn->data.events;
    ev.data.ptr = kn;

    return epoll_update(EPOLL_CTL_ADD, filt, kn, &ev);
}
Exemplo n.º 6
0
int
evfilt_read_knote_create(struct filter *filt, struct knote *kn)
{
    struct epoll_event ev;

    if (linux_get_descriptor_type(kn) < 0)
        return (-1);

    /* Convert the kevent into an epoll_event */
#if defined(HAVE_EPOLLRDHUP)
    kn->data.events = EPOLLIN | EPOLLRDHUP;
#else
    kn->data.events = EPOLLIN;
#endif
    if (kn->kev.flags & EV_ONESHOT || kn->kev.flags & EV_DISPATCH)
        kn->data.events |= EPOLLONESHOT;
    if (kn->kev.flags & EV_CLEAR)
        kn->data.events |= EPOLLET;

    memset(&ev, 0, sizeof(ev));
    ev.events = kn->data.events;
    ev.data.ptr = kn;

    /* Special case: for regular files, add a surrogate eventfd that is always readable */
    if (kn->kn_flags & KNFL_FILE) {
        int evfd;

        kn->kn_epollfd = filter_epfd(filt);
        evfd = eventfd(0, 0);
        if (evfd < 0) {
            dbg_perror("eventfd(2)");
            return (-1);
        }
        if (eventfd_write(evfd, 1) < 0) {
            dbg_perror("eventfd_write(3)");
            (void) close(evfd);
            return (-1);
        }

        kn->kdata.kn_eventfd = evfd;

        if (epoll_ctl(kn->kn_epollfd, EPOLL_CTL_ADD, kn->kdata.kn_eventfd, &ev) < 0) {
            dbg_printf("epoll_ctl(2): %s", strerror(errno));
            return (-1);
        }

        kn->kn_registered = 1;

        return (0);
    }

    return epoll_update(EPOLL_CTL_ADD, filt, kn, &ev);
}
Exemplo n.º 7
0
int
evfilt_read_knote_disable(struct filter *filt, struct knote *kn)
{
    if (kn->kn_flags & KNFL_REGULAR_FILE) {
        if (epoll_ctl(kn->kn_epollfd, EPOLL_CTL_DEL, kn->kdata.kn_eventfd, NULL) < 0) {
            dbg_perror("epoll_ctl(2)");
            return (-1);
        }
        return (0);
    } else {
        return epoll_update(EPOLL_CTL_DEL, filt, kn, NULL);
    }
}
Exemplo n.º 8
0
int
evfilt_read_knote_enable(struct filter *filt, struct knote *kn)
{
    struct epoll_event ev;

    memset(&ev, 0, sizeof(ev));
    ev.events = kn->data.events;
    ev.data.ptr = kn;

    if (kn->kn_flags & KNFL_REGULAR_FILE) {
        if (epoll_ctl(kn->kn_epollfd, EPOLL_CTL_ADD, kn->kdata.kn_eventfd, &ev) < 0) {
            dbg_perror("epoll_ctl(2)");
            return (-1);
        }
        return (0);
    } else {
        return epoll_update(EPOLL_CTL_ADD, filt, kn, &ev);
    }

    // clang will complain about not returning a value otherwise
    return (-1);
}
Exemplo n.º 9
0
int
evfilt_socket_knote_disable(struct filter *filt, struct knote *kn)
{
    return epoll_update(EPOLL_CTL_DEL, filt, kn, NULL);
}