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

Re: [Libevent-users] the relation between event loop and struct event variable lifetime and scope




I cannot help you with libevent 1.4 (I would use libevent 2 for new project). However, for creating events, you cannot use the stack.

The simplest solution would be to malloc a new event structure when you need a new event. You will have to free the event structure after you remove the event from the event loop.

For example:

struct event *pkt_ev = calloc(1, sizeof(*pkt_ev));

// Configure and add the event to the event loop...

// When you are done
free(pkt_ev);

You will probbaly need to keep the pointer to the event, so you can cancel the timer when you finished with the operation that needs a timeout. For example, maybe you want to create a struct that hold a packet and an event, and keep a table of these.

struct pkt_ctx {
    struct pkt pkt;
    struct event timeout;
};

On Wed, May 22, 2013 at 10:41 AM, wen lui <esolvepolito@xxxxxxxxx> wrote:

MY special case::
in the main
.c int main(){ struct event_base *base; struct event pcap_ev; ..... // here I get a file descriptor pcapfd event_set(&pcap_ev, pcapfd, EV_READ|EV_PERSIST, on_capture, pcap_handle); event_base_set(base, &pcap_ev); event_add(&pcap_ev, NULL); ..... event_base_dispatch(base); } on_capture callback function: void *on_capture(int pcapfd, short op, void *arg) { pcap_t *handle; handle = (pcap_t *)arg; fqueue_t* pkt_queue; pkt_queue = init_fqueue(); pcap_dispatch(handle, -1, collect_pkt, pkt_queue); // this function put all the cached packets into pkt_queue process_pcap(pkt_queue); } the sub-routine process_pcap(): void process_pcap(pkt_queue);{ for (pkt in pkt_queue){ // here is pseudo code insert(table, pkt); // here insert the pkt into a certain table struct event pkt_ev; evtimer_set(&pkt_ev, timer_cb, NULL); // I want to call timer_cb after timeout event_base_set(base, &pkt_ev); event_add(&pkt_ev, timeout); } } the callback function timer_cb(): timer_cb(...){ if(...) delete(table, pkt); ....... }


I'm just afraid timer_cb() won't be called because pkt_ev is a local variable.


2013/5/22 wen lui <esolvepolito@xxxxxxxxx>
 
void func(){ struct event ev1;
event_set(&ev1, ...);
event_base_set(base, &ev);
 event_add(&ev1, ...) } int main(){

struct event_base * mybase = event_init();
 
func(); event_base_dispatch(base);
 }
-----------------------------------------------------------------------------------------------------------------
the more complete version is as above. you mean the event_init() will create 2 event bases, the default base
and mybase? why will the memory used for the event be overwritten by random data if it is added to the
default base? if it is added to mybase, there is no problem?








Basically what you want to do is:

- Create new events when needed with event_new()
- Add the new events to base with event_add()
- Free your events when done with event_free()
--------------------------------------------------------------------------------------------------------------
event_new() is in libevent version 2.0.xxx, I'm using libevent version 1.4xxxx
I think the following 3 lines can replace event_new()
     struct event ev1;
     event_set(&ev1, ...);   
event_base_set(base, &ev);


I'm just afraid, if the event is created in a non-main sub-routine, then it is 
a local variable. its lifetime is inside that sub-routine. When event_add() is
called in that sub-routine, the event is added to event loop, but after that
subroutine is
finished, the local variable is game over. If libevent doesn't make
a copy of the event inside the event loop, there is a crash.

       



2013/5/22 Nir Soffer <nirsof@xxxxxxxxx>
On Wed, May 22, 2013 at 4:41 AM, wen lui <esolvepolito@xxxxxxxxx> wrote:
From stackoverflow I get to know that  if I define a struct event variable in a function which is different from where event_base_dispatch()
is defined, this event will not be added to the event loop, as below, ev1 will not be added to event loop.

   void func(){
     struct event ev1;

This event is on the stuck...
 

     event_set(&ev1, ...);
     event_add(&ev1, ...)

And you added it to the default event base.

If you dispatch the default base, you probably crash (soon if you are lucky). The memory used for the event will be overwritten by random data when another function is called.
 

   }

   int main(){
      func();

Here you dispatch on another base.
 

      event_base_dispatch(base);
 }

my problem is that I can't estimate the number of events in advance(think about discrete-event-driven simulation
if you know it, but I'm not using libevent
for this purpose). so I have to create one event each time a call back function or its sub-function wants to insert an event into the event_loop.
That's being said I need to create
many events that are local varibles which are not seen by
event_base_dispatch(base);

are there any workaround for my problem?
No, but reading libevent book may help.

Basically what you want to do is:

- Create new events when needed with event_new()
- Add the new events to base with event_add()
- Free your events when done with event_free()