知道所有回调都有 运行 with libevent 和 bufferevent_free
Knowing all callbacks have run with libevent and bufferevent_free
我正在使用 libevent 2.0.22 版做一些工作,我正在努力处理 bufferevent_free
并确保套接字在正确的时间关闭。这是在使用 Xcode 6.4、运行 在 iOS 8.4 上构建的 iOS 应用程序中。
每个套接字都由 struct bufferevent
管理,我还有一个数据结构来跟踪该套接字的应用程序状态:
bev = bufferevent_socket_new(evbase, -1, BEV_OPT_CLOSE_ON_FREE);
bufferevent_socket_connect_hostname(bev, dns_base, AF_UNSPEC, host, port_number);
struct stream_data *data = malloc(sizeof(struct stream_data));
/* initialize stream data here */
bufferevent_setcb(bev, read_cb, write_cb, event_cb, data);
在来自其他缓冲区套接字的回调中,我决定不需要刚刚尝试打开的缓冲区。这发生在 before 我在有问题的 bev 上得到了连接的回调。因为我用 BEV_OPT_CLOSE_ON_FREE
创建了它,所以我只是释放它。然后我删除我正在使用的数据结构。看起来像这样:
bufferevent_free(bev);
free(stream_data); // the data corresponding to that bev
不过,在这种情况下,套接字实际上同时完成了连接。所以我的事件回调触发:
void event_cb(struct bufferevent *bev, short what, void *ctx)
{
struct stream_data *data = ctx;
// data now points to already freed memory
}
现在我有一个指向已释放内存的指针。我已经通过调试器断点、NSLog
等确认事件回调在上面的 free
之后触发。
这是预期的行为吗?如果是这样,我怎么知道我释放的 bufferevent 已经完全消失,从而可以安全地删除我自己的数据结构?
是的,这是预期的 libevent 行为:在 bufferevent_free() 之后它仍然可以调用您的回调。来自 libevent 书:
Bufferevents are internally reference-counted, so if the bufferevent has pending deferred callbacks when you free it, it won’t be deleted until the callbacks are done.
最简单的解决方案是在释放 bufferevent 对象之前删除所有回调:
bufferevent_setcb(bev, NULL, NULL, NULL, NULL);
bufferevent_free(bev);
我正在使用 libevent 2.0.22 版做一些工作,我正在努力处理 bufferevent_free
并确保套接字在正确的时间关闭。这是在使用 Xcode 6.4、运行 在 iOS 8.4 上构建的 iOS 应用程序中。
每个套接字都由 struct bufferevent
管理,我还有一个数据结构来跟踪该套接字的应用程序状态:
bev = bufferevent_socket_new(evbase, -1, BEV_OPT_CLOSE_ON_FREE);
bufferevent_socket_connect_hostname(bev, dns_base, AF_UNSPEC, host, port_number);
struct stream_data *data = malloc(sizeof(struct stream_data));
/* initialize stream data here */
bufferevent_setcb(bev, read_cb, write_cb, event_cb, data);
在来自其他缓冲区套接字的回调中,我决定不需要刚刚尝试打开的缓冲区。这发生在 before 我在有问题的 bev 上得到了连接的回调。因为我用 BEV_OPT_CLOSE_ON_FREE
创建了它,所以我只是释放它。然后我删除我正在使用的数据结构。看起来像这样:
bufferevent_free(bev);
free(stream_data); // the data corresponding to that bev
不过,在这种情况下,套接字实际上同时完成了连接。所以我的事件回调触发:
void event_cb(struct bufferevent *bev, short what, void *ctx)
{
struct stream_data *data = ctx;
// data now points to already freed memory
}
现在我有一个指向已释放内存的指针。我已经通过调试器断点、NSLog
等确认事件回调在上面的 free
之后触发。
这是预期的行为吗?如果是这样,我怎么知道我释放的 bufferevent 已经完全消失,从而可以安全地删除我自己的数据结构?
是的,这是预期的 libevent 行为:在 bufferevent_free() 之后它仍然可以调用您的回调。来自 libevent 书:
Bufferevents are internally reference-counted, so if the bufferevent has pending deferred callbacks when you free it, it won’t be deleted until the callbacks are done.
最简单的解决方案是在释放 bufferevent 对象之前删除所有回调:
bufferevent_setcb(bev, NULL, NULL, NULL, NULL);
bufferevent_free(bev);