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