在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的更多相关文章

  1. Libevent源码分析 (1) hello-world

    Libevent源码分析 (1) hello-world ⑨月份接触了久闻大名的libevent,当时想读读源码,可是由于事情比较多一直没有时间,现在手头的东西基本告一段落了,我准备读读libeven ...

  2. 【转】libevent源码分析

    libevent源码分析 转自:http://www.cnblogs.com/hustcat/archive/2010/08/31/1814022.html 这两天没事,看了一下Memcached和l ...

  3. Libevent源码分析系列【转】

    转自:https://www.cnblogs.com/zxiner/p/6919021.html 1.使用libevent库     源码那么多,该怎么分析从哪分析呢?一个好的方法就是先用起来,会用了 ...

  4. Libevent源码分析系列

    1.使用libevent库     源码那么多,该怎么分析从哪分析呢?一个好的方法就是先用起来,会用了,然后去看底层相应的源码,这样比较有条理,自上向下掌握.下面用libevent库写个程序,每隔1秒 ...

  5. libevent源码分析

    这两天没事,看了一下Memcached和libevent的源码,做个小总结. 1.入门 1.1.概述Libevent是一个用于开发可扩展性网络服务器的基于事件驱动(event-driven)模型的网络 ...

  6. libevent源码分析二--timeout事件响应

    libevent不仅支持io事件,同时还支持timeout事件与signal事件,这篇文件将分析libevent是如何组织timeout事件以及如何响应timeout事件. 1.  min_heap ...

  7. libevent源码分析一--io事件响应

    这篇文章将分析libevent如何组织io事件,如何捕捉事件的发生并进行相应的响应.这里不会详细分析event与event_base的细节,仅描述io事件如何存储与如何响应. 1.  select l ...

  8. Libevent源码分析—event_init()

    下面开始看初始化event_base结构的相关函数.相关源码位于event.c event_init() 首先调用event_init()初始化event_base结构体 struct event_b ...

  9. Libevent源码分析—event, event_base

    event和event_base是libevent的两个核心结构体,分别是反应堆模式中的Event和Reactor.源码分别位于event.h和event-internal.h中 1.event: s ...

  10. Libevent源码分析—event_add()

    接下来就是将已经初始化的event注册到libevent的事件链表上,通过event_add()来实现,源码位于event.c中. event_add() 这个函数主要完成了下面几件事: 1.将eve ...

随机推荐

  1. python实现从生成器中取固定角标的元素

    #!/usr/bin/env python3 # -*- coding: utf-8 -*- class A: def __init__(self): def r(): i = 1 while Tru ...

  2. 用sublime写出的第一个网页

    STEP1 完成语义分析器 我用的vs2013 c语言写的 这个过程会在下一篇文章中详讲 准备好几个编译好的图,放在一个文件夹里,像下面这样 STEP2 规划好html的框架 上代码! (截图版) ( ...

  3. OC ---- 字符串 数组 iOS学习-----细碎知识点总结

    NSString *urlString = [NSString stringWithFormat:@"http://www.apple.com"];        // 获取字符串 ...

  4. imx6 DDR_Stress_Test

    在调试DDR的时候,有时候需要更改参数.今天发现NXP提供了DDR Stress Test工具,用于DDR参数的校准. 参考链接 http://blog.csdn.net/qq405180763/ar ...

  5. 带阈值的平滑l0范数加速稀疏恢复——同名英文论文翻译

    原文链接:Thresholded Smoothed l0 Norm for Accelerated Sparse Recovery http://ieeexplore.ieee.org/documen ...

  6. spring cloud的主要组成部分

    服务发现:Eureka断路器: Hystrix 客户端和控制面板客户端负载均衡: Ribbon声明式REST客户端: Feign外部化配置: Archaius路由和过滤器: Zuul RxJava w ...

  7. Java 动态代理作用是什么?

    Java 动态代理作用是什么?   1 条评论 分享   默认排序按时间排序 19 个回答 133赞同反对,不会显示你的姓名 Intopass 程序员,近期沉迷于动漫ING 133 人赞同 ① 首先你 ...

  8. 命令行下Git的使用

    命令行下Git的使用 写在前边的话 以自己即将进行的毕设项目为例,进行Git使用的简易说明.不过由于校园网络的限制,故使用GitOSC. 快速开始 本次git使用位于自己的个人PC上,所以将个人的Gi ...

  9. spring boot 添加jsp支持注意事项

    1.一定要使用war包<packaging>war</packaging>2.将provided改为compile,具体如下: <dependency> <g ...

  10. jQuery之元素的遍历与元素的过滤

    jQuery遍历之向下遍历 jQuery遍历之向上遍历 jQuery遍历之同级遍历 jQuery遍历之过滤