[Author Prev][Author Next][Thread Prev][Thread Next][Author Index][Thread Index]

Re: [Libevent-users] Infinity loop



On Mon, Oct 05, 2009 at 09:44:20AM +0200, nicolas dumont wrote:
> Hello
> 
> I've had the same behaviour, exactly in same function event_active()
> 
> It was due to the fact that I ran event_set() after doing event_add() of 
> the same event.
> In that case, the internal flags are resetted by the event_set().
> Then the event state is lost and can't be deleted,
> and because there's not trap for that in libevent code, you fall in 
> infinite loop.

Right.  You MUST NEVER EVER CALL event_set() ON AN EVENT THAT HAS BEEN
ADDED!  The event_set() function needs to be able to run on arbitrary
memory, and so it can't look at anything in the event structure to see
whether it's been added.

(It could look through the whole list of inserted events to see
whether the event has been added, but that would be an O(N) operation
and you probably wouldn't want to do that.)

Here's one way to make this error impossible: if you are using
Libevent 2.0, then only use event_new() to set up events.  If not, you
can define a fake event_new like this:

struct event *
my_event_new(struct event_base *base, int sock, short what,
             void (*cb)(int, short, void *), void *arg)
{
  struct event *e = malloc(sizeof(struct event));
  event_set(e, sock, what, cb, arg);
  if (base)
    event_base_set(base, e);
  return e;
}

void
my_event_free(struct event *ev)
{
  event_del(ev);
  free(ev);
}

This way, you never call event_set() on an event that might have
already been added, and so you do not risk changing its internal
state.  Heap-allocating all of your events might be too slow for some
applications, but in most cases it shouldn't slow the application
down.

Here are some other options that would involve patches (ideally
against Libevent 2.0) that somebody could write:
  - The timeout_process() function and the event_del_internal()
    function could try harder to notice this kind of user error,
    and exit instead of looping forever.
  - Somebody could write a "debug mode" patch that would let
    programmers set a "debug mode" on an event_base.  If debug mode
    were enabled, event_set() and event_assign() could walk over the
    list of inserted events before altering the event.

If anybody wants to write one of these but isn't sure how, just ask.

yrs,
-- 
Nick
***********************************************************************
To unsubscribe, send an e-mail to majordomo@xxxxxxxxxxxxx with
unsubscribe libevent-users    in the body.