On Tue, Nov 13, 2007 at 06:27:58PM -0800, William Ahern wrote:
> >     event_set(ev, fd, EV_READ | EV_PERSIST, read_cb, obj);
> >     event_add(ev, &timeout);
> > 
> > read_cb() will be called whenever a read event happens, and it's timeout
> > as passed to event_add() will be reset to the original value you passed.
> > You do not have to call event_add() within the handler.
> > 
> >     event_set(ev, -1, EV_TIMEOUT | EV_PERSIST, timer_cb, obj);
> >     event_add(ev, &cycle);
> > 
> > timer_cb() will be called when timeout (as passed via cycle) expires. It
> > will then reschedule itself with it's original timeout, e.g. periodic timer.
> > You do not have to call event_add() within the handler.
> 
> What was the original behavior? Did the timer disappear? If not, I fail to
> see how the new behavior is more justificed than the old; meaning, instead
> of changing it, why not add it as an option? If waiting to read an entire
> line, but you are trickled one byte at a time, do you really want to reset
> the timeout between bytes, or is the timeout meant to limit the time spent
> on reading the line?

The original behaviour with EV_PERSIST was this:

1. Implicitly not delete our event, but do not reschedule the timer.
2. Merrily read/write/signal/etc. on an event and then out of the blue
   receive EV_TIMEOUT because the timeout was never rescheduled unless you
   explicitly did it (which one probably won't inutitively expect with 
EV_PERSIST).

We went over this one before though. The issue is that the "attacker crafting
1 byte data to keep connection open for eternity" thing, while valid - I don't
really see how it's a libevent issue. That's an application issue. Otherwise,
with EV_PERSIST, the timeout added to the event no longer plays the role of
a timeout once a single event happens on said event, and the timeout is not
rescheduled manually.

The concept of a timeout being tied to "if we get a single unit of y bytes"
means the timeout is then a sideband module within said event now. However,
receive 1 byte == event occured - and based on - that timeout should no longer
be relevant to the situation that already occured.

The example you bring up of wanting to read y units of bytes in a given time is
still possible without EV_PERSIST, or by using an associated timer event 
(probably
not preferred), etc. It's just that the previous example is so much an
exception to the standard idiom of:

wait_until_event_or_timeout(); do_stuff() || delete_myself(); reset_timeout();

With EV_PERSIST as it is, it's only convenient for exceptional cases rather than
the norm - and that's the focus of this patch - to reverse that.

-cl

> 
> > For the event_del() changes, it's just moving event_del() into 
> > event_active(),
> > when an event occurs. There is a feature request on sourceforge for this,
> > and this couples nicely with the EV_PERSIST change. It also allows us to
> > rexamine the logic tests within the various event dispatchers themselves, as
> > event_active() will only delete the same event once.
> 
> Will this cause incompatabilities? What if you call event_add() anyhow? Will
> it return failure? This could silently break code. Maybe the user set
> EV_PERSIST, realized it didn't do what he wanted, but never removed it.

event_add() will then reschedule the event based on the timeout you passed to
it. But since it's already implicit with EV_PERSIST, it would just be a
redudant but safe thing to do.

-cl
_______________________________________________
Libevent-users mailing list
Libevent-users@monkey.org
http://monkeymail.org/mailman/listinfo/libevent-users

Reply via email to