libevent源码分析:event_assign、event_new

在libevent中,获取event类型对象的方法有两种,event_assign、event_new

1、event_assign()

 1 /**
 2   Prepare a new, already-allocated event structure to be added.
 3
 4   The function event_assign() prepares the event structure ev to be used
 5   in future calls to event_add() and event_del().  Unlike event_new(), it
 6   doesn‘t allocate memory itself: it requires that you have already
 7   allocated a struct event, probably on the heap.  Doing this will
 8   typically make your code depend on the size of the event structure, and
 9   thereby create incompatibility with future versions of Libevent.
10
11   The easiest way to avoid this problem is just to use event_new() and
12   event_free() instead.
13
14   A slightly harder way to future-proof your code is to use
15   event_get_struct_event_size() to determine the required size of an event
16   at runtime.
17
18   Note that it is NOT safe to call this function on an event that is
19   active or pending.  Doing so WILL corrupt internal data structures in
20   Libevent, and lead to strange, hard-to-diagnose bugs.  You _can_ use
21   event_assign to change an existing event, but only if it is not active
22   or pending!
23
24   The arguments for this function, and the behavior of the events that it
25   makes, are as for event_new().
26
27   @param ev an event struct to be modified
28   @param base the event base to which ev should be attached.
29   @param fd the file descriptor to be monitored
30   @param events desired events to monitor; can be EV_READ and/or EV_WRITE
31   @param callback callback function to be invoked when the event occurs
32   @param callback_arg an argument to be passed to the callback function
33
34   @return 0 if success, or -1 on invalid arguments.
35
36   @see event_new(), event_add(), event_del(), event_base_once(),
37     event_get_struct_event_size()
38   */
39 EVENT2_EXPORT_SYMBOL
40 int event_assign(struct event *, struct event_base *, evutil_socket_t, short, event_callback_fn, void *);

实现:

其实event_assign的作用就是把给定的event类型对象的每一个成员赋予一个指定的值。

 1 int
 2 event_assign(struct event *ev, struct event_base *base, evutil_socket_t fd, short events, void (*callback)(evutil_socket_t, short, void *), void *arg)
 3 {
 4     if (!base)
 5         base = current_base;
 6     if (arg == &event_self_cbarg_ptr_)
 7         arg = ev;
 8
 9     event_debug_assert_not_added_(ev);
10
11     ev->ev_base = base;
12
13     ev->ev_callback = callback;
14     ev->ev_arg = arg;
15     ev->ev_fd = fd;
16     ev->ev_events = events;
17     ev->ev_res = 0;
18     ev->ev_flags = EVLIST_INIT;
19     ev->ev_ncalls = 0;
20     ev->ev_pncalls = NULL;
21
22     if (events & EV_SIGNAL) {
23         if ((events & (EV_READ|EV_WRITE|EV_CLOSED)) != 0) {
24             event_warnx("%s: EV_SIGNAL is not compatible with "
25                 "EV_READ, EV_WRITE or EV_CLOSED", __func__);
26             return -1;
27         }
28         ev->ev_closure = EV_CLOSURE_EVENT_SIGNAL;
29     } else {
30         if (events & EV_PERSIST) {
31             evutil_timerclear(&ev->ev_io_timeout);
32             ev->ev_closure = EV_CLOSURE_EVENT_PERSIST;
33         } else {
34             ev->ev_closure = EV_CLOSURE_EVENT;
35         }
36     }
37
38     min_heap_elem_init_(ev);
39
40     if (base != NULL) {
41         /* by default, we put new events into the middle priority */
42         ev->ev_pri = base->nactivequeues / 2;
43     }
44
45     event_debug_note_setup_(ev);
46
47     return 0;
48 }

2、event_new()

 1 /**
 2   Allocate and asssign a new event structure, ready to be added.
 3
 4   The function event_new() returns a new event that can be used in
 5   future calls to event_add() and event_del().  The fd and events
 6   arguments determine which conditions will trigger the event; the
 7   callback and callback_arg arguments tell Libevent what to do when the
 8   event becomes active.
 9
10   If events contains one of EV_READ, EV_WRITE, or EV_READ|EV_WRITE, then
11   fd is a file descriptor or socket that should get monitored for
12   readiness to read, readiness to write, or readiness for either operation
13   (respectively).  If events contains EV_SIGNAL, then fd is a signal
14   number to wait for.  If events contains none of those flags, then the
15   event can be triggered only by a timeout or by manual activation with
16   event_active(): In this case, fd must be -1.
17
18   The EV_PERSIST flag can also be passed in the events argument: it makes
19   event_add() persistent until event_del() is called.
20
21   The EV_ET flag is compatible with EV_READ and EV_WRITE, and supported
22   only by certain backends.  It tells Libevent to use edge-triggered
23   events.
24
25   The EV_TIMEOUT flag has no effect here.
26
27   It is okay to have multiple events all listening on the same fds; but
28   they must either all be edge-triggered, or all not be edge triggerd.
29
30   When the event becomes active, the event loop will run the provided
31   callbuck function, with three arguments.  The first will be the provided
32   fd value.  The second will be a bitfield of the events that triggered:
33   EV_READ, EV_WRITE, or EV_SIGNAL.  Here the EV_TIMEOUT flag indicates
34   that a timeout occurred, and EV_ET indicates that an edge-triggered
35   event occurred.  The third event will be the callback_arg pointer that
36   you provide.
37
38   @param base the event base to which the event should be attached.
39   @param fd the file descriptor or signal to be monitored, or -1.
40   @param events desired events to monitor: bitfield of EV_READ, EV_WRITE,
41       EV_SIGNAL, EV_PERSIST, EV_ET.
42   @param callback callback function to be invoked when the event occurs
43   @param callback_arg an argument to be passed to the callback function
44
45   @return a newly allocated struct event that must later be freed with
46     event_free().
47   @see event_free(), event_add(), event_del(), event_assign()
48  */
49 EVENT2_EXPORT_SYMBOL
50 struct event *event_new(struct event_base *, evutil_socket_t, short, event_callback_fn, void *);

实现:

event_new的实现其实是间接的调用的event_assign,首先调用mm_malloc分配一块内存,然后调用event_assign来给event类型的对象各个成员赋值。

 1 struct event *
 2 event_new(struct event_base *base, evutil_socket_t fd, short events, void (*cb)(evutil_socket_t, short, void *), void *arg)
 3 {
 4     struct event *ev;
 5     ev = mm_malloc(sizeof(struct event));
 6     if (ev == NULL)
 7         return (NULL);
 8     if (event_assign(ev, base, fd, events, cb, arg) < 0) {
 9         mm_free(ev);
10         return (NULL);
11     }
12
13     return (ev);
14 }

3、区别

这两种方式的区别就是,event_assign是在栈上分配一个对象,然后给成员赋值;而event_new是在堆上分配一个对象,然后给成员赋值。

时间: 2024-11-03 01:37:13

libevent源码分析:event_assign、event_new的相关文章

Libevent源码分析 (1) hello-world

Libevent源码分析 (1) hello-world ⑨月份接触了久闻大名的libevent,当时想读读源码,可是由于事情比较多一直没有时间,现在手头的东西基本告一段落了,我准备读读libevent的源码,凡是我觉得有必要的内容均一一记录,与君共勉. 首先要说说什么是libevent: libevent是一个事件通知库,libevent API提供一种机制使得我们可以在一个文件描述符(file descriptor)发生特定事件时或者timeout发生时执行指定的回调函数.libevent意

Libevent源码分析-timer和signal处理

timer处理 Signal处理 timerfd和signalfd timerfd signalfd timer处理 在Libevent源码分析-event处理流程中,使用了定时器,来看一下源码: evtimer_set(&ev, time_cb, NULL);//设置定时器事件 其中evtimer_set是个宏定义 #define evtimer_set(ev, cb, arg) event_set((ev), -1, 0, (cb), (arg)) //event_set原型 void ev

【转】libevent源码分析

libevent源码分析 转自:http://www.cnblogs.com/hustcat/archive/2010/08/31/1814022.html 这两天没事,看了一下Memcached和libevent的源码,做个小总结. 1.入门 1.1.概述Libevent是一个用于开发可扩展性网络服务器的基于事件驱动(event-driven)模型的网络库.Libevent有几个显著的亮点: (1)事件驱动(event-driven),高性能:(2)轻量级,专注于网络,不如 ACE 那么臃肿庞

libevent源码分析-event

event结构 event相关接口 Libevent对event的管理 event结构 event是Reactor模式中的最重要的组件.它包含了了一个句柄fd,并设置监听这个句柄上的哪些事件(读/写等),设置了对应的函数指针,在事件到来时,回调函数指针来处理事件. 先看一下event的结构.它位于include/event2/event_struct.h中 struct event { TAILQ_ENTRY(event) ev_active_next; TAILQ_ENTRY(event) e

[libevent源码分析] event_init

libevent采用的是经典的reactor网络框架,集成了信号.定时.网络事件于一体 首先对event_init进行源码剖析 event_init 主要创建event_base对象, struct event_base { const struct eventop *evsel; //lievent支持select epoll kequeue..等网络api,包括init.add.del.dispatch的接口,每种网络框架都支持 void *evbase; //支持相应网络api的 结构对象

[libevent源码分析] event_set

libevent使用event来封装网络事件回调,参数.fd...等一些信息,函数很简单 void event_set(struct event *ev, int fd, short events, void (*callback)(int, short, void *), void *arg) { /* Take the current base - caller needs to set the real base later */ ev->ev_base = current_base; /

[libevent源码分析] event_add

event_add 把event往当前event中的ev_base追加,如果需要定时,那么tv不能为空 int event_add(struct event *ev, const struct timeval *tv) { struct event_base *base = ev->ev_base; //event_add 会把event加入到他的ev_base成员里 const struct eventop *evsel = base->evsel; //对应linux的epoll相关函数

[libevent源码分析] event_base_dispatch

分析下事件循环 event_base_dispatch int event_base_dispatch(struct event_base *event_base) { return (event_base_loop(event_base, 0)); } int event_base_loop(struct event_base *base, int flags) { const struct eventop *evsel = base->evsel; void *evbase = base->

Libevent源码分析系列【转】

转自:https://www.cnblogs.com/zxiner/p/6919021.html 1.使用libevent库 源码那么多,该怎么分析从哪分析呢?一个好的方法就是先用起来,会用了,然后去看底层相应的源码,这样比较有条理,自上向下掌握.下面用libevent库写个程序,每隔1秒输出一行信息. test.c 2.event, event_base 经过第1步,下面开始看上面程序中的每一部分的源码.首先是两个核心结构体event和event_base event event_base源码

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

这篇文章将分析libevent如何组织io事件,如何捕捉事件的发生并进行相应的操作.这里不会详细分析event与event_base的细节,仅描述io事件如何存储与如何响应. 1.  select libevent的实现io事件的backend实际上使用的是io复用接口,如select, poll, epoll等,这里以最简单的select为例进行说明.首先简单介绍一下select接口: int select(int nfds, fd_set *readfds, fd_set *writefds