Example of "epoll" usage? - Linux

This is a discussion on Example of "epoll" usage? - Linux ; Does anyone have reference to textbooks, URL, or Usenet posting which has example of "epoll" usages? There are few things that manpage is not clear about. (Sorry if it's repeat post... I posted few days ago, but I'm not seeing ...

+ Reply to Thread
Results 1 to 13 of 13

Thread: Example of "epoll" usage?

  1. Example of "epoll" usage?

    Does anyone have reference to textbooks, URL, or Usenet posting which
    has example of "epoll" usages? There are few things that manpage is not
    clear about.

    (Sorry if it's repeat post... I posted few days ago, but I'm not seeing
    it).

    --
    William Park , Toronto, Canada
    BashDiff: Super Bash shell
    http://freshmeat.net/projects/bashdiff/

  2. Re: Example of "epoll" usage?

    William Park writes:

    > Does anyone have reference to textbooks, URL, or Usenet posting which
    > has example of "epoll" usages? There are few things that manpage is not
    > clear about.


    Look at libevent, it includes support for epoll as well as many other
    poll-esque interfaces.

    --
    Grant Taylor
    Embedded Linux Consultant
    http://www.picante.com/

  3. Re: Example of "epoll" usage?

    William Park wrote:
    > Does anyone have reference to textbooks, URL, or Usenet posting which
    > has example of "epoll" usages? There are few things that manpage is not
    > clear about.
    >


    I know what you mean, I was recently in the process of learning epoll as well.
    Docs and examples ARE lacking. Go ahead and ask a question.

  4. Re: Example of "epoll" usage?

    shebble wrote:
    > William Park wrote:
    > > Does anyone have reference to textbooks, URL, or Usenet posting
    > > which has example of "epoll" usages? There are few things that
    > > manpage is not clear about.
    > >

    >
    > I know what you mean, I was recently in the process of learning epoll
    > as well. Docs and examples ARE lacking. Go ahead and ask a question.


    Thanks, here it goes...

    For poll(), you allocate
    struct pollfd {
    int fd;
    short events;
    revents;
    } array[3];
    and you set 'fd' and 'events' on input, and poll() sets 'revents' on
    output. So, after calling poll() like
    poll (array, 3, timeout);
    you simply examine 'revents' of array[0], array[1], and array[2].

    For "epoll", it looks like, epoll_ctl() is used to set 'events' on
    input, and epoll_wait() sets 'events' (same name) on output.

    1. So, do I have to allocate an array of struct epoll_event in
    epoll_wait()? That is, do I do

    int epfd = epoll_create (3);
    struct epoll_events array[3];

    epoll_wait (epfd, array, 3, timeout);

    Or, does epoll_wait() return a pointer to an internal array, which
    would be set up by epoll_ctl()? That is, do I do

    int epfd = epoll_create (3);
    struct epoll_events *array;

    epoll_wait (epfd, array, 3, timeout);

    2. If epoll_wait() returns 1, then do I examine only array[0]? Or, do
    I examine 'events' and 'data' of all 3 array elements, of which only
    one element will have non-zero 'events'?

    --
    William Park , Toronto, Canada
    BashDiff: Super Bash shell
    http://freshmeat.net/projects/bashdiff/

  5. Re: Example of "epoll" usage?

    William Park writes:

    [...]

    > For "epoll", it looks like, epoll_ctl() is used to set 'events' on
    > input, and epoll_wait() sets 'events' (same name) on output.
    >
    > 1. So, do I have to allocate an array of struct epoll_event in
    > epoll_wait()? That is, do I do
    >
    > int epfd = epoll_create (3);
    > struct epoll_events array[3];
    >
    > epoll_wait (epfd, array, 3, timeout);
    >
    > Or, does epoll_wait() return a pointer to an internal array, which
    > would be set up by epoll_ctl()?


    Obviously[*], the former. You pass a pointer to an array of structures
    and epoll_wait uses this array to return events to you.
    [*] Neither the syscall nor any conceivable C-library wrapper
    has any knowledge wrt memory usage requirements the caller
    needs to obey to. The only 'generally useful' interface is
    therefore one, where the caller allocates the array somewhere
    it sees fit.

    [...]

    > 2. If epoll_wait() returns 1, then do I examine only array[0]? Or, do
    > I examine 'events' and 'data' of all 3 array elements, of which only
    > one element will have non-zero 'events'?


    The sensible assumption would be that the elements of the array are
    used in order, if only because this is the most straight-forward to
    program. And that's what the implementation (../fs/eventpoll.c,
    ep_send_events) actually does.


  6. Re: Example of "epoll" usage?

    William Park wrote:
    > shebble wrote:
    >> William Park wrote:
    >>> Does anyone have reference to textbooks, URL, or Usenet posting
    >>> which has example of "epoll" usages? There are few things that
    >>> manpage is not clear about.
    >>>

    >> I know what you mean, I was recently in the process of learning epoll
    >> as well. Docs and examples ARE lacking. Go ahead and ask a question.

    >
    > Thanks, here it goes...
    >
    > For poll(), you allocate
    > struct pollfd {
    > int fd;
    > short events;
    > revents;
    > } array[3];
    > and you set 'fd' and 'events' on input, and poll() sets 'revents' on
    > output. So, after calling poll() like
    > poll (array, 3, timeout);
    > you simply examine 'revents' of array[0], array[1], and array[2].
    >
    > For "epoll", it looks like, epoll_ctl() is used to set 'events' on
    > input, and epoll_wait() sets 'events' (same name) on output.
    >


    Well epoll_ctl() is used to configure the wait. Specify file descriptor and what
    you want to watch about it (input, output, a few other things.., if you want to
    do edge triggered). Call it once for each fd you want to add.

    > 1. So, do I have to allocate an array of struct epoll_event in
    > epoll_wait()? That is, do I do
    >
    > int epfd = epoll_create (3);
    > struct epoll_events array[3];
    >
    > epoll_wait (epfd, array, 3, timeout);
    >


    Right.

    > Or, does epoll_wait() return a pointer to an internal array, which
    > would be set up by epoll_ctl()? That is, do I do
    >
    > int epfd = epoll_create (3);
    > struct epoll_events *array;
    >
    > epoll_wait (epfd, array, 3, timeout);
    >


    No.

    > 2. If epoll_wait() returns 1, then do I examine only array[0]? Or, do
    > I examine 'events' and 'data' of all 3 array elements, of which only
    > one element will have non-zero 'events'?
    >


    epoll_wait() returns the number of file descriptors ready(<- something
    happened). They will be copied into your array. This is not your entire set!
    Only fds which have had events. You need to check which fds and which events
    they are if it matters to you. Something like:

    int nfds = epoll_wait(...array...);
    for ( i = 0; i < nfds; i++ )
    {
    if ( array[ i ].data.fd == fd_1 && array[ i ].events == blah..)
    {
    // do something about fd_1
    }
    }

    Might want to check for error in epoll_wait too (-1).
    This is my understanding of it.


  7. Re: Example of "epoll" usage?

    shebble wrote:
    > William Park wrote:
    > > 2. If epoll_wait() returns 1, then do I examine only array[0]? Or,
    > > do I examine 'events' and 'data' of all 3 array elements, of
    > > which only one element will have non-zero 'events'?

    >
    > epoll_wait() returns the number of file descriptors ready(<- something
    > happened). They will be copied into your array. This is not your
    > entire set! Only fds which have had events. You need to check which
    > fds and which events they are if it matters to you. Something like:
    >
    > int nfds = epoll_wait(...array...);


    What I meant to ask is if you're supposed to check 'array[0]' to
    'array[nfds-1]'. In poll(), you have to check the entire array, because
    sequence of array elements are fixed at input. I guess, judging from
    the code below, you only check the first 'nfds' elements when using
    epoll(). :-)

    Thanks. That clears up the main issues for me, at the moment.

    > for ( i = 0; i < nfds; i++ )
    > {
    > if ( array[ i ].data.fd == fd_1 && array[ i ].events == blah..)
    > {
    > // do something about fd_1
    > }
    > }
    >
    > Might want to check for error in epoll_wait too (-1).
    > This is my understanding of it.


    --
    William Park , Toronto, Canada
    BashDiff: Super Bash shell
    http://freshmeat.net/projects/bashdiff/

  8. Re: Example of "epoll" usage?

    William Park writes:
    > shebble wrote:
    >> William Park wrote:
    >> > 2. If epoll_wait() returns 1, then do I examine only array[0]? Or,
    >> > do I examine 'events' and 'data' of all 3 array elements, of
    >> > which only one element will have non-zero 'events'?

    >>
    >> epoll_wait() returns the number of file descriptors ready(<- something
    >> happened). They will be copied into your array. This is not your
    >> entire set! Only fds which have had events. You need to check which
    >> fds and which events they are if it matters to you. Something like:
    >>
    >> int nfds = epoll_wait(...array...);

    >
    > What I meant to ask is if you're supposed to check 'array[0]' to
    > 'array[nfds-1]'.


    And the answer is still identical to the one I already posted
    yesterday: The epoll-code in the kernel returns n events in the array
    positions 0 .. n - 1.

    > poll(), you have to check the entire array, because sequence of
    > array elements are fixed at input.


    You have to check the entire array, because the same array was used to
    specify the interest set and the kernel returns events for particular
    descriptors in the revents-member of the structure associated with
    them.

    > I guess, judging from
    > the code below, you only check the first 'nfds' elements when using
    > epoll(). :-)


    That's indeed what the example code in the epoll(7)-manpage does ...


  9. Re: Example of "epoll" usage?

    Rainer Weikusat wrote:
    > William Park writes:
    >
    >> I guess, judging from
    >> the code below, you only check the first 'nfds' elements when using
    >> epoll(). :-)

    >
    > That's indeed what the example code in the epoll(7)-manpage does ...
    >


    And in fact it looks to me like you could even pass an array of size one to
    epoll_wait.. i.e. something smaller then your 'set'. So I guess the events would
    queue up as you pulled them one at a time. ?

  10. Re: Example of "epoll" usage?

    On Feb 8, 12:11 pm, shebble wrote:

    > And in fact it looks to me like you could even pass an array of size one to
    > epoll_wait.. i.e. something smaller then your 'set'. So I guess the events would
    > queue up as you pulled them one at a time. ?


    Yes if they were edge triggered, no if they were level triggered. If
    they're level triggered, you'll likely get the same event over and
    over.

    If you consume the event (by accepting the connection, reading the
    data, or writing until write blocks) then you'll get a new event
    either way.

    DS

  11. Re: Example of "epoll" usage?

    shebble wrote:
    > Rainer Weikusat wrote:
    > > William Park writes:
    > >> I guess, judging from the code below, you only check the first
    > >> 'nfds' elements when using epoll(). :-)

    > >
    > > That's indeed what the example code in the epoll(7)-manpage does ...

    >
    > And in fact it looks to me like you could even pass an array of size
    > one to epoll_wait.. i.e. something smaller then your 'set'. So I guess
    > the events would queue up as you pulled them one at a time. ?


    Thanks Rainer and shebble.

    One thing that I'm finding is that turning on/off 'events' bits is not
    as easy as in select()/poll(). For example, turning on EPOLLOUT bit
    only when there is something to write, but leaving EPOLLIN bit alone
    since you're always looking for incoming data.

    --
    William Park , Toronto, Canada
    BashDiff: Super Bash shell
    http://freshmeat.net/projects/bashdiff/

  12. Re: Example of "epoll" usage?

    David Schwartz wrote:
    > On Feb 8, 12:11 pm, shebble wrote:
    >
    >> And in fact it looks to me like you could even pass an array of size one to
    >> epoll_wait.. i.e. something smaller then your 'set'. So I guess the events would
    >> queue up as you pulled them one at a time. ?

    >
    > Yes if they were edge triggered, no if they were level triggered. If
    > they're level triggered, you'll likely get the same event over and
    > over.
    >
    > If you consume the event (by accepting the connection, reading the
    > data, or writing until write blocks) then you'll get a new event
    > either way.
    >
    > DS


    Ok, right that would be important. I AM assuming that one is 'consuming' the
    events after each wait.

  13. Re: Example of "epoll" usage?

    On Feb 8, 5:57 pm, William Park wrote:

    > One thing that I'm finding is that turning on/off 'events' bits is not
    > as easy as in select()/poll(). For example, turning on EPOLLOUT bit
    > only when there is something to write, but leaving EPOLLIN bit alone
    > since you're always looking for incoming data.


    The easiest way to do it, IMO, is to set the EPOLLOUT bit whenever you
    have "leftover" from a write operation. Clear the EPOLLOUT bit
    whenever you have emptied your send queue.

    DS

+ Reply to Thread