Hi Christopher,

I created a tracker item for this at:

  
https://sourceforge.net/tracker/?func=detail&atid=461325&aid=1831173&group_id=50884

Let's discuss potential resolutions there.

Thank you,
 Niels.

On Nov 13, 2007 1:24 AM, Christopher Layne <[EMAIL PROTECTED]> wrote:
> As it is, EV_PERSIST is somewhat obtuse when trying to use it in combination
> with EV_READ or EV_WRITE while still handling timeout events. The standard
> idiom is basically:
>
> if (select_epoll_etc_indicates_something)
>         do_something_and_add_fd_back_to_something_set();
> else if (time_since_last_something > something_timeout)
>         our_client_or_server_is_dead_lets_cleanup();
>
> One method is to do something like this with EV_PERSIST is:
>
> void read_cb(int fd, short event, void *a)
> {
>         opaque *obj = a;
>         ssize_t l;
>
>         switch (event) {
>         case EV_TIMEOUT:
>                 close_cleanup_whatever(fd);
>                 opaque_reset(obj);
>                 event_del(obj->ev_r);
>                 break;
>         case EV_READ:
>                 l = recv(fd, ...);
>                 /*
>                  * Here we force a timeout reschedule. if we don't,
>                  * our timeout will eventually trigger, regardless
>                  * of the fact that we've been processing active events.
>                  * It isn't really added with EV_PERSIST, just the timeout
>                  * is rescheduled.
>                  */
>                 event_add(obj->ev_r, obj->tout_recv_tv);
>                 break;
>         default: break;
>         }
>
>         return;
> }
>
> Same goes for EV_SIGNAL and EV_TIMEOUT events. event_add(event, timeout),
> always, if you want to reschedule the timer associated with it (which for
> all intensive purposes you almost always will if you're using EV_PERSIST
> in the first place).
>
> Now it's not like this is a huge hassle, but it does seem like it would
> be more inutitive for libevent to handle latching timers of this sort when
> using EV_PERSIST. I've written a patch to handle latching timers when using
> EV_PERSIST and currently I can see some pros and cons.
>
> Pros:
> 1. EV_PERSIST + anything else works intuitively without having to worry
>         about managing the timeout one passed to event_add(). Set it and
>         forget it.
> 2. For some people it may be one less thing to truck around in their god
>         objects. I.e. the space taken up by storing the relative timer within
>         the event struct itself is balanced by the space saved by not carrying
>         it around in user objects. Not a gain, however, for people using
>         global timeout structs.
> 3. It's not really much of a boogeyman to current users of libevent as the
>         people who are using EV_PERSIST typically are aware of said timeout
>         issues. Also, the current workaround of event_add() will work fine
>         in existing code.
> 4. Focuses on optimizing the standard case rather than the exception 
> (timeout).
>
> Cons:
> 1. Cyclic timer still needs event_add() in the callback, as a timeout is
>         still setup to delete the event automatically. I'm torn on this. If
>         it's changed it will break current behaviour. If it isn't changed,
>         then it's another thing to remember when using the library - that is
>         events registered with EV_PERSIST will have their timeouts reset on
>         activity, however a timeout occuring will automatically delete the
>         event as per normal. In day to day usage this is probably a preferred
>         idiom though, even though it's an exception to the latching timer
>         pattern. One concern though is that since things are less explicit,
>         flow is not as self-evident.
> 2. Timeout rescheduling is done when event_active() is called. This is not
>         entirely precise because event timeouts may end up being rescheduled
>         to a slightly earlier moment in time. One way to get around this is to
>         move timeout_schedule() to event_process_active(), but it would take
>         some reworking of timeout_process().
> 3. Maybe this is all just a waste of time and we should just continue to use
>         event_add(obj, obj->tout);
>
>
> With the model changed, it would look like this:
>
> void read_cb(int fd, short event, void *a)
> {
>         opaque *obj = a;
>         ssize_t l;
>
>         switch (event) {
>         case EV_TIMEOUT:
>                 close_cleanup_whatever(fd);
>                 opaque_reset(obj);
>                 break;
>         case EV_READ:
>                 l = recv(fd, ...);
>                 /* etc */
>                 break;
>         default: break;
>         }
>
>         return;
> }
>
> void dispatcher(opaque *obj)
> {
>         event_set(obj->ev_r, obj->fd, EV_READ | EV_PERSIST, read_cb, obj);
>         event_add(obj->ev_r, obj->tout_recv_tv);
>         return;
> }
>
> Interested to hear thoughts before I go posting patches.
>
> -cl
> _______________________________________________
> Libevent-users mailing list
> Libevent-users@monkey.org
> http://monkeymail.org/mailman/listinfo/libevent-users
>
>
_______________________________________________
Libevent-users mailing list
Libevent-users@monkey.org
http://monkeymail.org/mailman/listinfo/libevent-users

Reply via email to