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()
>>>>>
>>>>>
>>>>>
>>>>
>>>
>>
>