libevent:如果事件是由 malloc 创建的,是不是允许在其回调函数中释放事件

Posted

技术标签:

【中文标题】libevent:如果事件是由 malloc 创建的,是不是允许在其回调函数中释放事件【英文标题】:libevent: is it allowed to free an event inside its callback function if the event is created by malloclibevent:如果事件是由 malloc 创建的,是否允许在其回调函数中释放事件 【发布时间】:2013-05-22 12:00:21 【问题描述】:

我需要使用 malloc 创建事件,但我不知道在哪里释放它们,我想知道 是否允许在其回调函数中释放事件,例如:

struct event *pkt_ev = (struct event *)malloc(sizeof(struct event));
evtimer_set(&pkt_ev, timer_cb, &pkt_ev);    
event_base_set(base, &pkt_ev); 
event_add(&pkt_ev, timeout);

回调函数timer_cb():

    timer_cb(int fd, short ev, void* arg)
    .......
    free(arg);    // here the arg is &pkt_ev

我最初的想法是:回调函数timer_cb()被调用后,libevent会隐式调用event_del(&pkt_ev)。但是由于我在回调中释放了&pkt_ev,所以event_del(&pkt_ev) 上会出现崩溃/异常。对吗?

但是,如果event_del(&pkt_ev) 不在乎pkt_ev 指向什么内容,那可能不是问题?

此外,在这个函数中:

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

ev指向的内容要多注意,一般应该是全局变量或者生命周期要覆盖事件循环(即事件循环函数在运行时会访问@指向的内容987654332@)。 timeout指向的内容呢? timeout 指向的内容是否应该覆盖事件循环?

【问题讨论】:

【参考方案1】:

你的第一个假设是错误的,libevent 隐式调用event_del() 之前调用回调函数,而不是之后(假设未设置 EV_PERSIST 标志)。因此,如果未设置 EV_PERSIST 标志,则在回调中释放 pkt_ev 没有问题。如果设置了,需要先显式调用event_del()

关于你的第二个问题,不,超时指向的内容是在event_add()返回之前复制的。

【讨论】:

以上是关于libevent:如果事件是由 malloc 创建的,是不是允许在其回调函数中释放事件的主要内容,如果未能解决你的问题,请参考以下文章

一起读读libevent的源代码:Libevent 第二章 创建Event base

如果我想要事件驱动服务器,该使用啥 libevent 或 libev?

如何将参数传递给使用 libevent 创建的事件函数?

Libevent:event

同一 fd 上不同线程中的多个 libevent 基础

libevent : 如果相关套接字被本地程序关闭,是不是可以触发事件