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

Re: [Libevent-users] infinite loop in evmap_io_active



On Mon, Apr 11, 2011 at 3:16 PM, Mike Cui <cuicui@xxxxxxxxx> wrote:
>> "One reason that can happen
>> is if you add an event, then re-assign it and re-add it without first
>> deleting it.  To debug that, try enabling debug mode by calling
>>    event_enable_debug_mode();
>> near the start of your program (before you construct any event_bases).
>>
>> It should detect any attempts to modify an event that's currently pending."
>
> Yep. I was not calling event_del(). So question, if I want to
> reschedule a event, I can call event_add() multiple times. But calling
> event_del() deletes the event forever?

No; event_del() makes the event non-pending.  I've tried to explain
this in the documentation at
http://www.wangafu.net/~nickm/libevent-book/Ref4_event.html , and in
the doxygen documentation.

Here's how it works: a chunk of memory that you get from
malloc(sizeof(struct event)) or by declaring "struct event x;" starts
out as uninitialized RAM.  You can turn this memory into an event with
event_assign().  You can also get a new event with event_new().

These "newly initialized" events are not "pending" (that is, libevent
is not watching for events on them), and they are not "active" (that
is, libevent is not planning to run their callbacks).  This is the
only state in which it is safe to reinitialize an event with
event_assign(), or to free malloc'd memory with free().

Calling event_active() on an event makes it "active": libevent will
schedule its callback to be run in the event loop.

Calling event_add() on an event makes it "pending": libevent will
start its timer (if it has one), and start watching its fd and/or
signal (if it has one).  "Pending" events are also called "added"
events sometimes.

An event can be "active" and "pending" at the same time.

Calling event_del() on an event returns it to the "newly initialized"
state.  If it was active and the callback hasn't been run it, it won't
get run.

If an event is pending, and the event triggers (that is, its fd/signal
becomes active or its fd expires), then the event will become
"active".  If the EV_PERSIST flag was set on the event, then it will
still be pending; otherwise, it will no longer be pending.

When an active event's callback is run, it becomes inactive.

It is okay to free any initialized event with event_free(), since
event_free() includes an event_del() operation.

Here is are some things that it is  _not_ okay to do:
  * Call event_set or event_assign() on an event that is pending or active.
  * Call free() on an event that is still pending or active, or allow
a stack-allocated event that is pending or active to go out of scope.
  * Call event_free() on an event that was not returned from event_new().

I've drawn up a draft state transition diagram.  It's not pretty, but
it might help:
   http://www.wangafu.net/~nickm/volatile/event_states.png
Please let me know if I've got anything wrong; I want to include it in
the book if I can figure out how.  That URL isn't permanent.

Did this answer your questions?

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