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.
The only solution I found, in order to be sure that I won't fall into this infinite loop. ( And because I use a lot of events, and that was to complex to rewrite all the events architecture of my software)
Is to patch the event_set() and run event_del()at the beginning of event_set like this :
event_set(struct event *ev, int fd, short events,
void (*callback)(int, short, void *), void *arg)
{
+ if ((ev->ev_flags & EVLIST_DEL_ALL) != 0 )
+ {
+ event_debug(("event_set: ev %p,ev_flags 0x%X call event_del(), ev is
not correctly initialized",
+ ev,ev->ev_flags)); + event_del(ev); + assert((ev->ev_flags & EVLIST_DEL_ALL) == 0); + } + with : +#define EVLIST_DEL_ALL (EVLIST_TIMEOUT|EVLIST_INSERTED|EVLIST_ACTIVE) But, be careful with that solution !!!It implies to initialize to 0 the struct event before doing the first event_set() !!!!
Here is a copy of the mail I've sent to libevent mailing list :
>Hi,
>
>I'm using events in 1.4.12-stable.
>
>Sometimes, my daemon, which uses event_base_loop()
>goes in an infinite loop ( verbose traces below ).
>
>This infinite loop is inside function event_process_active() which
>calls event_del() with ev_flags=0x80 ( =EVLIST_INIT)
>This flags is not managed by event_del(), then the ev is never deleted
>from the queue, then the loop "for" retries again and again.
>
>static void event_process_active(struct event_base *base)
>{
>...
> for (ev = TAILQ_FIRST(activeq); ev; ev = TAILQ_FIRST(activeq)) {
> if (ev->ev_events & EV_PERSIST)
> event_queue_remove(base, ev, EVLIST_ACTIVE);
> else
> event_del(ev);
>...
> }
>}
>
>
>[2009-08-26 17:12:29] ev : event_add: event: 0xb13a7e0, EV_READ
>call 0x280b789c
>[2009-08-26 17:12:29] ev : kq_insert: fd 43 EVFILT_READ
>[2009-08-26 17:12:29] ev : event_queue_insert queue=0x2 ev_flags=0x1082
>[2009-08-26 17:12:29] ev : event_process_active: call event_del
>[2009-08-26 17:12:29] ev : event_del: 0xb13e6a0, callback 0x280b7dd4,
>ev_flags 0x1082 ev_events 0x2
>[2009-08-26 17:12:29] ev : event_queue_remove queue=0x2 ev_flags=0x1080
>[2009-08-26 17:12:29] ev : kq_insert: fd 74 EVFILT_READ (del)
>[2009-08-26 17:12:29] ev : event_process_active: call event_del
>[2009-08-26 17:12:29] ev : event_del: 0xb13e6a0, callback 0x280b7dd4,
>ev_flags 0x80 ev_events 0x2
>[2009-08-26 17:12:29] ev : event_process_active: call event_del
>[2009-08-26 17:12:29] ev : event_del: 0xb13e6a0, callback 0x280b7dd4,
>ev_flags 0x80 ev_events 0x2
>[2009-08-26 17:12:29] ev : event_process_active: call event_del
>[2009-08-26 17:12:29] ev : event_del: 0xb13e6a0, callback 0x280b7dd4,
>ev_flags 0x80 ev_events 0x2
>[2009-08-26 17:12:29] ev : event_process_active: call event_del
>[2009-08-26 17:12:29] ev : event_del: 0xb13e6a0, callback 0x280b7dd4,
>ev_flags 0x80 ev_events 0x2
>[2009-08-26 17:12:29] ev : event_process_active: call event_del
>[2009-08-26 17:12:29] ev : event_del: 0xb13e6a0, callback 0x280b7dd4,
>ev_flags 0x80 ev_events 0x2
>.....
>....
>...
>..
>.
>
>After investigating my code, I found that I call in this order :
>
>event_set(&ev, EV_READ,callback_one);
>event_add(&ev);
>
>and later :
>event_set(&ev, EV_READ,callback_two);
>
>The pb is that the second event_set which is called to set another
callback resets the ev->flags with EVLIST_INIT
>After that I fall into the infinite loop describe behind. >>So, even if I'm doing something wrong with the usage of the API, it should not go in an infinite loop.
> >Finnaly, to prevent to go in the infinite loop , >do I have to run event_del(&ev) each time before using event_set(&ev) ? > >Thank's a lot for your answer. Hereafter is the answer from libevnet team :
This is exactly so. You can't call event_set or event_assign on an event while it is added. Unfortunately, because event_set works on uninitialized memory, there is no way for it to check whether it's looking at an added event, or a random chunk of memory that happens to have bits set in the right place.
Best regards, Nicolas Dumont. -- Nicolas Dumont System Team Leader NETASQ - We secure IT 3 rue Archimede 59650 Villeneuve d'Ascq France Tel : +33 (0)3.20.61.90.44Fax : +33 (0)3.20.61.97.48
Attachment:
smime.p7s
Description: S/MIME Cryptographic Signature