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