Re: [PATCH] /dev/epoll update ...

From: Davide Libenzi (davidel@xmailserver.org)
Date: Wed Sep 19 2001 - 21:28:04 EST


On 20-Sep-2001 Dan Kegel wrote:
> Davide Libenzi wrote:
>> 1) if (recv()/send() == FAIL)
>> 2) ioctl(EP_POLL);
>
> A lot of people, including me, were under the mistaken impression
> that /dev/epoll, like /dev/poll, provided an efficient way to
> retrieve the current readiness state of fd's. I understand from your post
> that /dev/epoll's purpose is to retrieve state changes; in other
> words, it's exactly like F_SETSIG/F_SETOWN/O_ASYNC except that
> the readiness change indications are picked up via an ioctl
> rather than via a signal.
>
> A scorecard for the confused (Davide, correct me if I'm wrong):
>
> * API's that allow you to retrieve the current readiness state of
> a set of fd's: poll(), select(), /dev/poll, kqueue().
> Buzzwords describing this kind of interface: level-triggered, multishot.
>
> * API's that allow you to retrieve *changes* to the readiness state of
> a set of fd's: F_SETSIG/F_SETOWN/O_ASYNC + sigtimedwait(), /dev/epoll, kqueue().
> Buzzwords describing this kind of interface: edge-triggered, single-shot.
>
> (Note that kqueue is in both camps.)
>
> Er, I guess that means I'll rip up the /dev/epoll support I based on my
> /dev/poll code, and replace it with some based on my O_ASYNC code...

Exactly :)
Here are examples basic functions when used with coroutines :

int dph_connect(struct dph_conn *conn, const struct sockaddr *serv_addr, socklen_t addrlen) {

        if (connect(conn->sfd, serv_addr, addrlen) == -1) {
                if (errno != EWOULDBLOCK && errno != EINPROGRESS)
                        return -1;
                conn->events = POLLOUT | POLLERR | POLLHUP;
                co_resume(conn);
                if (conn->revents & (POLLERR | POLLHUP))
                        return -1;
        }
        return 0;
}

int dph_read(struct dph_conn *conn, char *buf, int nbyte) {
        int n;

        while ((n = read(conn->sfd, buf, nbyte)) < 0) {
                if (errno == EINTR)
                        continue;
                if (errno != EAGAIN && errno != EWOULDBLOCK)
                        return -1;
                conn->events = POLLIN | POLLERR | POLLHUP;
                co_resume(conn);
        }
        return n;
}

int dph_write(struct dph_conn *conn, char const *buf, int nbyte) {
        int n;

        while ((n = write(conn->sfd, buf, nbyte)) < 0) {
                if (errno == EINTR)
                        continue;
                if (errno != EAGAIN && errno != EWOULDBLOCK)
                        return -1;
                conn->events = POLLOUT | POLLERR | POLLHUP;
                co_resume(conn);
        }
        return n;
}

int dph_accept(struct dph_conn *conn, struct sockaddr *addr, int *addrlen) {
        int sfd;

        while ((sfd = accept(conn->sfd, addr, (socklen_t *) addrlen)) < 0) {
                if (errno == EINTR)
                        continue;
                if (errno != EAGAIN && errno != EWOULDBLOCK)
                        return -1;
                conn->events = POLLIN | POLLERR | POLLHUP;
                co_resume(conn);
        }
        return sfd;
}

- Davide

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/



This archive was generated by hypermail 2b29 : Sun Sep 23 2001 - 21:00:35 EST