【问题标题】:libevent API: understanding the pointer parameters or return valueslibevent API:了解指针参数或返回值
【发布时间】:2013-05-21 22:34:39
【问题描述】:

对于以下 libevent API:

void event_set(struct event *ev, int fd, short event, void (*cb)(int, short, void *), void *arg)

event_add(struct event *ev, const struct timeval *timeout); 

struct event* event_new (struct event_base *, evutil_socket_t, short, event_callback_fn, void)   

我想知道:

1) 对于第二个函数event_add 中的指针参数ev,函数event_add 是否制作了ev 结构的本地副本?

例如,如果我这样做:

  code snippet 1:

     struct event ev;
     event_set(&ev, ..para list 1...);    // event 1 
     event_add(&ev, ...);
     event_set(&ev, ..para list 2...);    // event 2
     event_add(&ev, ...);

event 1 和 event 2 不同,因为参数列表 1 和参数列表 2 不同。如果 event_add 做本地副本,那么没问题,但是如果 event_add 不做本地副本,那么这两个@987654326 @居然只加了事件2?

另外,如果我有一个主要功能:

   void func(){
     struct event ev;
     event_set(&ev, ...);
     event_add(&ev, ...)
   }

   int main(){
      func();
      event_base_dispatch(base);
   }

func() 被调用后,执行返回到 main()。因为ev 是 func() 中的一个局部变量。如果 event_add(&ev,...) 不做本地副本,那么ev 无处可寻,就会有问题。 那么我可以在本地事件结构上调用 event_add() 吗?

我想不时添加许多计时器事件(使用类似 evtimer_set 的东西),并且添加发生在一些回调函数中。所以我不能提前为超时事件定义全局变量,如果不能对局部变量调用event_add(),有什么解决办法吗?

2)event_new返回一个结构体指针,我想知道结构体在哪里,是栈/堆内存还是静态内存?

我的特殊情况:

        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);
                     .......
                }

我只是担心timer_cb() 不会被调用,因为pkt_ev 是一个局部变量。

【问题讨论】:

    标签: c libevent


    【解决方案1】:

    对于您想了解的每个事件,您必须使用不同的 struct event 实例。您只能在本地 struct event 变量上调用 event_add(),前提是该变量的生命周期跨越对事件循环 API 的所有调用,直到它被 event_del() 删除。

    分配函数默认使用堆,但您可以将自己的分配例程替换为event_set_mem_functions()

    【讨论】:

    • You must use a different struct event instance for each event you want to know about.,为什么? event_add() 不制作本地副本?
    • 我更新了我的问题,如果 event_add() 没有进行本地复制,那么如果在子函数内的本地 struct event 变量上调用它,会导致问题吗?
    • 如果 struct event 是本地且非静态的(不在 event_loop 函数所在的函数内),它的生命周期如何跨越对事件循环 API 的所有调用(event_base_dispatch())?非静态局部变量的生命周期就在定义它的函数内部。
    • 在我看来,我需要为每个事件创建全局变量。我想不时添加许多计时器事件(使用evtimer_set之类的东西),并且添加发生在一些回调函数中。所以我不能提前为超时事件定义全局变量,有没有解决方案?谢谢!
    • 对于调度,我的意思是调度是否发生在同一个函数中。对于计时器,您应该在收到回调时关联回某个事件上下文对象。在我的代码中,我通常每个连接都有一个这样的对象。这个“连接对象”包含我想要设置/取消设置的所有其他东西,比如计时器等。
    猜你喜欢
    • 2018-05-30
    • 1970-01-01
    • 2014-06-25
    • 1970-01-01
    • 1970-01-01
    • 2019-08-22
    • 1970-01-01
    • 2017-09-05
    相关资源
    最近更新 更多