sorry, I forgot another variable:

                  event_add(struct event *ev, struct timeval *tv);

how about the content pointed by tv?  int the following program, the
content pointed by tv
is in stack and its scope/lifetime is not covered by
event_base_loop(main_base, 0);
but the program runs well, it is by coincedence or it is a correct usage?

thanks!



static struct event_base *main_base;
volatile rel_time_t current_time;

static void set_current_time(void)
{
        struct timeval timer;
        gettimeofday(&timer, NULL);
        current_time = (rel_time_t) (timer.tv_sec);
}
static void clock_handler(const int fd, const short which, void *arg)
{
        if(arg){ free(arg); printf("free an event!\n");}
        struct event *clockevent = (struct event *)malloc(sizeof(struct event));
        struct timeval tv = {.tv_sec = 1, .tv_usec = 0 };
        static bool initialized = false;
        if(initialized){
                evtimer_del(clockevent);
        }else{
                initialized = true;
        }
        evtimer_set(clockevent, clock_handler, clockevent);
        event_base_set(main_base, clockevent);
        evtimer_add(clockevent, &tv);
        set_current_time();
        printf("current_time: %d\n", current_time);
}
int main()
{
        main_base = event_init();
        clock_handler(0, 0, NULL);
        event_base_loop(main_base, 0);

        return 0;
}



2013/5/22 wen lui <[email protected]>

> 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