Subject: Re: Only select and poll?

Re: Only select and poll?

From: Uli <ToBeSpammed_at_web.de>
Date: Tue, 04 Sep 2007 16:44:10 +0200

Daniel Stenberg wrote:
> On Mon, 3 Sep 2007, Uli wrote:
>> The only way I found is using ares_getsock(), adding each of those fds
>> for epoll and removing them after epoll_wait() which isn't a nice way
>> of doing this.
>
> I added ares_getsock() for the purpose of extracting the sockets for
> this purpose. I don't quite see why you need to remove them afer
> epoll_wait(), but then I'm not an expert on epoll.

epoll uses its own kind of fds created by epoll_create(). To that fd I can add
sockets with something like this (example for stdin):

        struct epoll_event ev;
        ev.events = EPOLLIN;
        ev.data.u64 = 0;
        epoll_ctl(fd, EPOLL_CTL_ADD, 0, &ev);

That means the kernel manages the list of sockets and I don't build a list (or
have a list) of all my sockets on each call to epoll_wait().
ev.data can BTW be any data I like and the kernel returns that to me when an
event on that socket happened:

        struct epoll_events events[5];
        int timeout = 1000; /* msecs */
        int nfds;

        nfds = epoll_wait(fd, events, sizeof(events), timeout);

nfds is the number of fields in events[] which are set. In each field the bit
masks ev.events tell me which events happened and ev.data is the data i set on
epoll_ctl(). Sockets which are close()d are automatically removed.

If I want to use epoll() I call epoll_ctl(fd, EPOLL_CTL_ADD,...); for each
socket I created once and don't have to bother about it again. The problem now
is that I don't have a way to do this for c-ares as I only can get a complete
list of sockets it's interested in.

So now my idea was to use ares_getsock() to get a list of sockets, add each with
epoll_ctl() (which is one syscall per socket :/) and remove them after
epoll_wait(), because else I get EEXIST when I add them again on the next loop.
The right way in this case would be EPOLL_CTL_MOD if I want to change ev.events
(read / write / out-of-band-data).

Since this would need much state-tracking I instead remove the sockets
afterwards again.

I hope to have made my problem clearer and I'm sorry but I have no idea for a
nice API-call to handle this. Perhaps some call backs for when a socket is
created / removed / it changes if c-ares wants to read/write from it?

Uli Schlachter

-- 
   c-ares -- also my preferred DNS asynch resolver library ;)
Received on 2007-09-04