changelist-internal.h定义了一个结构体struct event_change结构体。
我们在调用backend's dispatch 函数之前可能会对一个event做修改,比如改它的事件类型,或者添加新的事件类型,甚至是添加或者删除event,libevent用struct event_change 结构体记录在调用backend's dispatch 函数之前一个更改的event。
struct event_change {而所有的event_change用event_changelist管理,
/** 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
/* List of 'changes' since the last call to eventop.dispatch. Only maintained为什么要修改一个event,不直接处理呢,而是要把它放到event_changelist链表中稍后再处理?
* if the backend is using changesets. */
struct event_changelist {
struct event_change *changes;
int n_changes;
int changes_size;
};
因为:
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);