thank you very much, I understand a lot. I still have 3 questions:

1)   it is a bit troublesome if I need to maintain and deal with an
additional table which cache the timeout event. The program is running
according to event loop, then WHEN can I call free() on those timer events?
If I can free the event inside the callback function, then it is much more
convenient, is it possible? like:

                           evtimer_set(&pkt_ev, timer_cb, &pkt_ev);
                           event_base_set(base, &pkt_ev);
                           event_add(&pkt_ev, timeout);


         the callback function timer_cb():

                timer_cb(int fd, short ev, void* arg){
                     if(...)  delete(table, pkt);
                     .......

                *free(arg); *   // here the arg is &pkt_ev

          }


my initial thinking is:  after the callback function timer_cb() is called,
the libevent will implicitly call event_del(&pkt_ev). But I freed
&pkt_ev inside
the callback, there will be a crash/exception on event_del(&pkt_ev). is it
right?
but if event_del(&pkt_ev) doesn't care what content pkt_ev points to, it
might not be a problem?


2) why do you  use the following line to set every byte of the event to 1,
is there any special reason?

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

3) Still I'm not clear on the  event_init() function.

according to your explanation and my understanding, when this function
event_init() is called as below, libevent will create 2 event bases, the
default base(global)and  mybase(local variable), if I don't explicitly bind
an event to mybase, it will be bound to the default base.
is my understanding correct?

                             struct event_base * mybase = event_init();


thank you!







2013/5/22 Nir Soffer <[email protected]>

>
> 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 <[email protected]> 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 <[email protected]>
>>
>>>
>>>
>>>    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 <[email protected]>
>>>
>>>> On Wed, May 22, 2013 at 4:41 AM, wen lui <[email protected]>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.
>>>> http://www.wangafu.net/~nickm/libevent-book/
>>>>
>>>> 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()
>>>>
>>>>
>>>>
>>>
>>
>

Reply via email to