libevent源码分析:event_assign、event_new
在libevent中,获取event类型对象的方法有两种,event_assign、event_new
1、event_assign()
/**
Prepare a new, already-allocated event structure to be added. The function event_assign() prepares the event structure ev to be used
in future calls to event_add() and event_del(). Unlike event_new(), it
doesn't allocate memory itself: it requires that you have already
allocated a struct event, probably on the heap. Doing this will
typically make your code depend on the size of the event structure, and
thereby create incompatibility with future versions of Libevent. The easiest way to avoid this problem is just to use event_new() and
event_free() instead. A slightly harder way to future-proof your code is to use
event_get_struct_event_size() to determine the required size of an event
at runtime. Note that it is NOT safe to call this function on an event that is
active or pending. Doing so WILL corrupt internal data structures in
Libevent, and lead to strange, hard-to-diagnose bugs. You _can_ use
event_assign to change an existing event, but only if it is not active
or pending! The arguments for this function, and the behavior of the events that it
makes, are as for event_new(). @param ev an event struct to be modified
@param base the event base to which ev should be attached.
@param fd the file descriptor to be monitored
@param events desired events to monitor; can be EV_READ and/or EV_WRITE
@param callback callback function to be invoked when the event occurs
@param callback_arg an argument to be passed to the callback function @return 0 if success, or -1 on invalid arguments. @see event_new(), event_add(), event_del(), event_base_once(),
event_get_struct_event_size()
*/
EVENT2_EXPORT_SYMBOL
int event_assign(struct event *, struct event_base *, evutil_socket_t, short, event_callback_fn, void *);
实现:
其实event_assign的作用就是把给定的event类型对象的每一个成员赋予一个指定的值。
int
event_assign(struct event *ev, struct event_base *base, evutil_socket_t fd, short events, void (*callback)(evutil_socket_t, short, void *), void *arg)
{
if (!base)
base = current_base;
if (arg == &event_self_cbarg_ptr_)
arg = ev; event_debug_assert_not_added_(ev); ev->ev_base = base; ev->ev_callback = callback;
ev->ev_arg = arg;
ev->ev_fd = fd;
ev->ev_events = events;
ev->ev_res = ;
ev->ev_flags = EVLIST_INIT;
ev->ev_ncalls = ;
ev->ev_pncalls = NULL; if (events & EV_SIGNAL) {
if ((events & (EV_READ|EV_WRITE|EV_CLOSED)) != ) {
event_warnx("%s: EV_SIGNAL is not compatible with "
"EV_READ, EV_WRITE or EV_CLOSED", __func__);
return -;
}
ev->ev_closure = EV_CLOSURE_EVENT_SIGNAL;
} else {
if (events & EV_PERSIST) {
evutil_timerclear(&ev->ev_io_timeout);
ev->ev_closure = EV_CLOSURE_EVENT_PERSIST;
} else {
ev->ev_closure = EV_CLOSURE_EVENT;
}
} min_heap_elem_init_(ev); if (base != NULL) {
/* by default, we put new events into the middle priority */
ev->ev_pri = base->nactivequeues / ;
} event_debug_note_setup_(ev); return ;
}
2、event_new()
/**
Allocate and asssign a new event structure, ready to be added. The function event_new() returns a new event that can be used in
future calls to event_add() and event_del(). The fd and events
arguments determine which conditions will trigger the event; the
callback and callback_arg arguments tell Libevent what to do when the
event becomes active. If events contains one of EV_READ, EV_WRITE, or EV_READ|EV_WRITE, then
fd is a file descriptor or socket that should get monitored for
readiness to read, readiness to write, or readiness for either operation
(respectively). If events contains EV_SIGNAL, then fd is a signal
number to wait for. If events contains none of those flags, then the
event can be triggered only by a timeout or by manual activation with
event_active(): In this case, fd must be -1. The EV_PERSIST flag can also be passed in the events argument: it makes
event_add() persistent until event_del() is called. The EV_ET flag is compatible with EV_READ and EV_WRITE, and supported
only by certain backends. It tells Libevent to use edge-triggered
events. The EV_TIMEOUT flag has no effect here. It is okay to have multiple events all listening on the same fds; but
they must either all be edge-triggered, or all not be edge triggerd. When the event becomes active, the event loop will run the provided
callbuck function, with three arguments. The first will be the provided
fd value. The second will be a bitfield of the events that triggered:
EV_READ, EV_WRITE, or EV_SIGNAL. Here the EV_TIMEOUT flag indicates
that a timeout occurred, and EV_ET indicates that an edge-triggered
event occurred. The third event will be the callback_arg pointer that
you provide. @param base the event base to which the event should be attached.
@param fd the file descriptor or signal to be monitored, or -1.
@param events desired events to monitor: bitfield of EV_READ, EV_WRITE,
EV_SIGNAL, EV_PERSIST, EV_ET.
@param callback callback function to be invoked when the event occurs
@param callback_arg an argument to be passed to the callback function @return a newly allocated struct event that must later be freed with
event_free().
@see event_free(), event_add(), event_del(), event_assign()
*/
EVENT2_EXPORT_SYMBOL
struct event *event_new(struct event_base *, evutil_socket_t, short, event_callback_fn, void *);
实现:
event_new的实现其实是间接的调用的event_assign,首先调用mm_malloc分配一块内存,然后调用event_assign来给event类型的对象各个成员赋值。
struct event *
event_new(struct event_base *base, evutil_socket_t fd, short events, void (*cb)(evutil_socket_t, short, void *), void *arg)
{
struct event *ev;
ev = mm_malloc(sizeof(struct event));
if (ev == NULL)
return (NULL);
if (event_assign(ev, base, fd, events, cb, arg) < ) {
mm_free(ev);
return (NULL);
} return (ev);
}
3、区别
这两种方式的区别就是,event_assign是在栈上分配一个对象,然后给成员赋值;而event_new是在堆上分配一个对象,然后给成员赋值。
libevent源码分析:event_assign、event_new的更多相关文章
- Libevent源码分析 (1) hello-world
Libevent源码分析 (1) hello-world ⑨月份接触了久闻大名的libevent,当时想读读源码,可是由于事情比较多一直没有时间,现在手头的东西基本告一段落了,我准备读读libeven ...
- 【转】libevent源码分析
libevent源码分析 转自:http://www.cnblogs.com/hustcat/archive/2010/08/31/1814022.html 这两天没事,看了一下Memcached和l ...
- Libevent源码分析系列【转】
转自:https://www.cnblogs.com/zxiner/p/6919021.html 1.使用libevent库 源码那么多,该怎么分析从哪分析呢?一个好的方法就是先用起来,会用了 ...
- Libevent源码分析系列
1.使用libevent库 源码那么多,该怎么分析从哪分析呢?一个好的方法就是先用起来,会用了,然后去看底层相应的源码,这样比较有条理,自上向下掌握.下面用libevent库写个程序,每隔1秒 ...
- libevent源码分析
这两天没事,看了一下Memcached和libevent的源码,做个小总结. 1.入门 1.1.概述Libevent是一个用于开发可扩展性网络服务器的基于事件驱动(event-driven)模型的网络 ...
- libevent源码分析二--timeout事件响应
libevent不仅支持io事件,同时还支持timeout事件与signal事件,这篇文件将分析libevent是如何组织timeout事件以及如何响应timeout事件. 1. min_heap ...
- libevent源码分析一--io事件响应
这篇文章将分析libevent如何组织io事件,如何捕捉事件的发生并进行相应的响应.这里不会详细分析event与event_base的细节,仅描述io事件如何存储与如何响应. 1. select l ...
- Libevent源码分析—event_init()
下面开始看初始化event_base结构的相关函数.相关源码位于event.c event_init() 首先调用event_init()初始化event_base结构体 struct event_b ...
- Libevent源码分析—event, event_base
event和event_base是libevent的两个核心结构体,分别是反应堆模式中的Event和Reactor.源码分别位于event.h和event-internal.h中 1.event: s ...
- Libevent源码分析—event_add()
接下来就是将已经初始化的event注册到libevent的事件链表上,通过event_add()来实现,源码位于event.c中. event_add() 这个函数主要完成了下面几件事: 1.将eve ...
随机推荐
- Mysql中实现row_number
CREATE TABLE `zsl_test` ( `ID` INT(10) NULL DEFAULT NULL, `class` INT(10) NULL DEF ...
- 另一种在WINFORM中使用XNA的方法
之前在写化学分子模型制作程序的时候,使用一种方法,将WINFORM控件嵌入到XNA窗体中,从而实现了即使用WINFORM窗体控件又使用XNA.最近在写另一个物理运动学课件制作程序,同样使用XNA,但从 ...
- orange pi pc 体验(一)
最近在淘宝上看到一款和树莓派差不多的卡片机,定价才99元,而且是国产的,忍不住入手了一个,就是orange pi 感兴趣的可以百度搜索下,深圳一个公司出的,不过资料比树莓派少了很多,论坛中人也没多少, ...
- SELENIUM2 使用JavascriptExecutor在页面Javascipt执行
目的: 1. 执行一段JS,来改变HTML2. 一些非标准控件无法用selenium2的API时,可以执行JS的办法来取代 主要操作:JavascriptExecutor j = (Javascrip ...
- linux下普通用户如何使用80端口启动程序
linux下普通用户如何使用80端口启动程序 http://blog.csdn.net/shootyou/article/details/6750230 大家都知道默认情况下linux的1024以下端 ...
- 一、oracle数据库成功安装步骤 (11gR2)
下载安装包 从Oracle官方网站下载数据库软件安装包:http://www.oracle.com/technetwork/cn/database/enterprise-edition/downloa ...
- Spring操作指南-IoC基础环境配置(基于注解自动装配)
项目源码:http://code.taobao.org/p/LearningJavaEE/src/LearningSpring001%20-%20Automatically%20wiring%20be ...
- 《 spring mvc 》学习计划
第一章:1月1日-1月2日 第二章:1月3日 第三章:1月4日 第四章:1月5日 第五章:1月6日-1月7日 第六章:1月8日 第七章:1月9日 第八章:1月10日 第九章:1月11日-1月12日 第 ...
- 图解jmeter压测http接口
此次压力测试是以一个http json的后台接口为例. 1. 创建相应的部件 2. 设置相应的参数 线程组主要用于设置一共要测试的线程数量(上图1000),每秒起的线程数(上图10),几秒内启动完单循 ...
- PAT线性结构_一元多项式求导、按给定步长反转链表、出栈序列存在性判断
02-线性结构1. 一元多项式求导 (25) 设计函数求一元多项式的导数.(注:xn(n为整数)的一阶导数为n*xn-1.) 输入格式:以指数递降方式输入多项式非零项系数和指数(绝对值均为不超过100 ...