tech-userlevel archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

Re: kqueue



On Mon, Jan 18, 2010 at 09:04:29PM +0000, Sad Clouds wrote:
> On Monday 18 January 2010 19:28:01 Joerg Sonnenberger wrote:
> 
> > > 2. Connected sockets. Does kevent return when any new data arrives into
> > > the socket buffer, or does it always return, provided socket buffer has
> > > more than SO_RCVLOWAT bytes of data?
> > 
> > This is documented in kevent(2).
> 
> The man page says:
> 
> EVFILT_READ
> 
> Other socket descriptors return when there is data to be read, subject to the 
> SO_RCVLOWAT value of the socket buffer.
> 
> So it seems to suggest that kevent always returns as long as socket is 
> readable. If I call kevent and it returns with 600 bytes of data, and then I 
> call kevent again with the socket still holding 600 bytes of the same data, 
> kevent will return as before.
> 
> However this guy says the opposite:
> 
> http://tedunangst.com/kqueue.pdf
> 
> On page 3, under "Dangers and Caveats" he says:
> ... 
> So which way is it then?

The manpage is right without EV_CLEAR.  One must use EV_CLEAR to
get the behaviour described by the guy in the Caveats section.

I've tested this on Mac OS X and NetBSD with attached program.
If I don't use EV_CLEAR, the second kevent() returns immediatelly.
Second kevent() blocks if the code is modified to set EV_CLEAR flag.

Jaromir
-- 
Jaromir Dolecek <jdolecek%NetBSD.org@localhost>            http://www.NetBSD.cz/
-=- We can walk our road together if our goals are all the same;     -=-
-=- We can run alone and free if we pursue a different aim.          -=-
#include <sys/types.h>
#include <sys/event.h>
#include <sys/time.h>
#include <sys/socket.h>
#include <sysexits.h>

int
main()
{
        int sock[2];
        struct kevent kc;
        int kq;
        char foo[1024];

        if (socketpair(PF_LOCAL, SOCK_STREAM, 0, sock) < 0)
                err(EX_TEMPFAIL, "socketpair");

        EV_SET(&kc, sock[1], EVFILT_READ, EV_ADD, 0, 0, 0);

        kq = kqueue();
        if (kevent(kq, &kc, 1, NULL, 0, NULL) < 0)
                err(EX_TEMPFAIL, "kqueue");

        if (write(sock[0], foo, sizeof(foo)) < 0)
                err(EX_TEMPFAIL, "write");

        if (kevent(kq, NULL, 0, &kc, 1, NULL) < 0)
                err(EX_TEMPFAIL, "kevent1");
        if (kevent(kq, NULL, 0, &kc, 1, NULL) < 0)
                err(EX_TEMPFAIL, "kevent2");
}


Home | Main Index | Thread Index | Old Index