libevent基础文件changelist-internal.h(struct event_change结构体)

时间:2023-01-25 00:15:10

changelist-internal.h定义了一个结构体struct event_change结构体。

我们在调用backend's dispatch 函数之前可能会对一个event做修改,比如改它的事件类型,或者添加新的事件类型,甚至是添加或者删除event,libevent用struct event_change 结构体记录在调用backend's dispatch 函数之前一个更改的event。

struct event_change {
/** The fd or signal whose events are to be changed */
evutil_socket_t fd;
/* The events that were enabled on the fd before any of these changes
were made. May include EV_READ or EV_WRITE. */
short old_events;

/* The changes that we want to make in reading and writing on this fd.
* If this is a signal, then read_change has EV_CHANGE_SIGNAL set,
* and write_change is unused. */
ev_uint8_t read_change;
ev_uint8_t write_change;
};
/* Flags for read_change and write_change. */


/* If set, add the event. */
#define EV_CHANGE_ADD     0x01
/* If set, delete the event.  Exclusive with EV_CHANGE_ADD */
#define EV_CHANGE_DEL     0x02
/* If set, this event refers a signal, not an fd. */
#define EV_CHANGE_SIGNAL  EV_SIGNAL
/* Set for persistent events.  Currently not used. */
#define EV_CHANGE_PERSIST EV_PERSIST
/* Set for adding edge-triggered events. */
#define EV_CHANGE_ET      EV_ET
而所有的event_change用event_changelist管理,

/* List of 'changes' since the last call to eventop.dispatch.  Only maintained
* if the backend is using changesets. */
struct event_changelist {
struct event_change *changes;
int n_changes;
int changes_size;
};
为什么要修改一个event,不直接处理呢,而是要把它放到event_changelist链表中稍后再处理?

因为:

1、应用程序可能会在调用dispatch方法之前多次添加或者删除一个相同的event。立即处理这些改变是不必要的,同时可能会有昂贵的代价(特别是每次event改变就要做一次系统调用的时候)

2、一个fd上多个改变通过一次系统调用就可以完成,比如epoll可以同时add和delete。

3、第三个不分析。

同时还声明了以下操作event_changelist的函数:

/** Set up the data fields in a changelist. */
void event_changelist_init(struct event_changelist *changelist);
/** Remove every change in the changelist, and make corresponding changes
* in the event maps in the base. This function is generally used right
* after making all the changes in the changelist. */
void event_changelist_remove_all(struct event_changelist *changelist,
struct event_base *base);
/** Free all memory held in a changelist. */
void event_changelist_freemem(struct event_changelist *changelist);

/** Implementation of eventop_add that queues the event in a changelist. */
int event_changelist_add(struct event_base *base, evutil_socket_t fd, short old, short events,
void *p);
/** Implementation of eventop_del that queues the event in a changelist. */
int event_changelist_del(struct event_base *base, evutil_socket_t fd, short old, short events,
void *p);