Level-triggering vs State-change triggering
Horacio Sanson
hsanson at gmail.com
Wed Nov 3 15:30:01 CET 2010
On Wednesday 03 November 2010 05:51:42 AJ ONeal wrote:
> > When I tried listening for when it was writable, it seemed to fire the
> > event over and over again.
> > I didn't think that was particularly helpful.
>
> Libev is Level-Triggered that means that as long as the socket write buffer
> has
> space you will keep getting the write event. You can read the man page of
> epoll (e.g. man epoll) for a small description about level-triggered vs
> edge-
> triggered events.
>
> I was expecting a state-change mechanism (is that edge-triggered?):
>
> If the socket is changed not writable, but was most recently writable, the
> event would fire.
> If the socket is changed writable, but was most recently not writable, the
> event would fire.
> If I registered a new callback listening to writable, and it was still
> writable, the event would fire.
>
I am also learning this things myself so do not take my words as written on
stone.
What you describe is edge triggered. The event is triggered only on state
changes (e.g. from writable to not writable and from not writable to
writable).
Epoll allows you to use both level-triggered and edge-triggered. What the man
page is warning you about is that in edge-triggered your application is
resposible of making sure you do something with the event. For example if you
get a readable event in edge-triggered and your application for some reason
forgets to actually read the data, epoll will simply assume is your
responsibility and will not tell you again that there is still data readable.
In level-triggered mode you will get the event as long as there is data for
reading and that is the same reason you will keep getting the writable event
all the time if you start the watcher.
These details are good to know but if you use libev then you do not need to
worry about this. Only remember that libev is level-triggered.
> So the reasoning is that libev can tell at the moment that it checks what
> state it is currently, but not when the state changes?
> It looks like epoll doesn't handle this case very gracefully from the
> snippet in the manpage that I read.
>
> AJ ONeal
>
> On Tue, Nov 2, 2010 at 1:26 AM, Horacio Sanson <hsanson at gmail.com> wrote:
> > On Tuesday 02 November 2010 13:44:58 AJ ONeal wrote:
> > > I believe that I've done this Unix Socket Echo Server "the right way"
> >
> > now:
> > > http://github.com/coolaj86/libev-examples/blob/master/unix-echo.c
> > >
> > > The question that I have is if it's true to say that a unix socket is
> > > writable whenever it is readable?
> >
> > no it is not.
> >
> > > When I tried listening for when it was writable, it seemed to fire the
> > > event over and over again.
> > > I didn't think that was particularly helpful.
> >
> > Libev is Level-Triggered that means that as long as the socket write
> > buffer has
> > space you will keep getting the write event. You can read the man page of
> > epoll (e.g. man epoll) for a small description about level-triggered vs
> > edge-
> > triggered events.
> >
> > > Or is it that when I want to send data I should
> > >
> > > start the watcher for writes
> > > send the data
> > > stop the watcher
> > >
> > > ?
> >
> > this is how I do the writes with libev:
> > when I want to send data:
> > send directly to the socket
> > if the send fails with EWOULDBLOCK
> >
> > store the data that could not be send in a buffer
> > start the write watcher
> >
> > else if the send fails with other error
> >
> > close the client
> >
> > In the write callback
> >
> > stop the write watcher
> > resend data you previously stored after EWOULDBLOCK
> > if the resend failed with EWOULDBLOCK
> >
> > store the data that could not be send in a buffer
> > start the write watcher again
> >
> > else if the send fails with other error
> >
> > close the client
> >
> > Esentially when I need to send data I simply send it to through the
> > socket and
> > only if the send fails with EWOULDBLOCK (that means the write socket
> > buffer is
> > full) then I start the write watcher so libev can tell me when there is
> > more
> > room in the socket write buffer to send more data. In the write callback
> > then I
> > stop the watcher and resume sending the data that could not be send
> > previously.
> >
> > > Now who wants to change the Unix Socket stuff out for TCP?
> > > I may eventually get around to it, but that's not what I need right
> > > now, interestingly enough.
> > >
> > > I'll try my hand at a client now.
> > >
> > > AJ ONeal
> > >
> > > On Mon, Nov 1, 2010 at 10:03 AM, AJ ONeal <coolaj86 at gmail.com> wrote:
> > > > Thank you for the link, but this is beyond my current scope of
> > > > understanding.
> > > > I was hoping for a simple example.
> > > >
> > > > I'm trying to start out small and learn my way up.
> > > >
> > > > Things like this and the dns example are a bit too heavy for me to
> > > > able to bite off in a chunk, digest, and take the next bite.
> > > >
> > > > If I also had a call graph, that would help a lot with an example
> > > > like this, but on it's own there are just too many layers to jump
> > > > back and forth between to understand what's going on.
> > > >
> > > > Do you happen to have a doxygen/dot (or other) call graph for this
> >
> > code?
> >
> > > > AJ ONeal
> > > >
> > > > On Mon, Nov 1, 2010 at 9:03 AM, common at gmx.ch <common at gmx.ch> wrote:
> > > >> AJ ONeal wrote:
> > > >>> Thanks.
> > > >>>
> > > >>> I'll keep playing with mine to see if I can get it right, but
> > > >>> please show me yours as soon as you have it up.
> > > >>
> > > >> It's part of a larger project, it does
> > > >>
> > > >> * tcp
> > > >> * udp
> > > >> * tls (via nonblocking openssl)
> > > >> * IPV4 & IPv6
> > > >> * unix domain sockets
> > > >> * client & server
> > > >> * rate limiting (in & out) per connection
> > > >> * resolve domains inline & nonblocking, so you can just
> > > >>
> > > >> connection_connect("example.com",80);
> > > >>
> > > >> and provides timeouts for almost everything you want to be able to
> > > >> control, listen, idle, sustain, accept, handshake for ssl
> > > >>
> > > >> http://src.carnivore.it/dionaea/tree/src/connection.c
> > > >>
> > > >>
> > > >> Markus
> >
> > --
> > regards,
> > Horacio Sanson
> >
> > _______________________________________________
> > libev mailing list
> > libev at lists.schmorp.de
> > http://lists.schmorp.de/cgi-bin/mailman/listinfo/libev
--
regards,
Horacio Sanson
More information about the libev
mailing list