On Feb 26, 2007, at 2:57 PM, Christian Ress wrote:

Hello,

I stumbled across libevent and it seems to fit my needs very well.
However, I wonder if this is side-effect free:

second_cb(..) { .. }
first_cb(..) {
  ..
  struct event newev;
  evtimer_set(&newev, second_cb, NULL);
  event_base_set(ev_base, &newev);
  event_add(&newev, &tv);

  event_base_dispatch(ev_base);
}

main() {
  ..
  ev_base = event_init();
  evtimer_set(ev, first_cb, NULL);
  event_add(ev, &tv);

  event_base_dispatch(ev_base);
}

The point of this is creating new events 'on demand', but since I'm calling event_dispatch when being called by event_loop, I wonder if this might lead to recursion issues or similar bad behaviour.

I hope someone can clarify this :)

First, keep in mind something that tripped up me when I first started using libevent - the "struct event" you pass to event_add is not duplicated, but rather directly linked into the event_base's queues. So if it's a timeout, it needs to live until it fires (or forever with EV_PERSIST) or you manually call event_del(). There are a lot of reasons that might not happen in the next invocation of event_base_dispatch(), so this code seems dangerous.

And second...while I don't see anything off-hand in libevent that would break based on this recursion, I don't think it was intended to be used that way, and you always risk stack overflows if you don't have a way to bound your recursion.

You can create new events 'on demand' with event_once. Which isn't magic - it just internally allocates a new struct event on the heap that adds a callback which - after calling your callback - frees the struct event. You could accomplish the same thing yourself:

void
first_cb(int fd, short events, void *arg)
{
    struct event *newev;
    int res;

    ...

    newev = malloc(sizeof(struct event));
    ...newev == NULL error handling goes here...
    evtimer_set(newev, ...);
    res = event_add(&newev, &tv);
    ...event_add error handling goes here...
}

void
second_cb(int fd, short events, void *arg)
{
    struct event *myev = arg;

    ...
    free(myev);
}

--
Scott Lamb <http://www.slamb.org/>


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

Reply via email to