Sometimes applications will add and delete the same event more than once between calls to dispatch. Processing these changes immediately is needless, and potentially expensive (especially if we’re on a system that makes one syscall per changed event). Sometimes we can coalesce multiple changes on the same fd into a single syscall if we know about them in advance. For example, epoll can do an add and a delete at the same time, but only if we have found out about both of them before we tell epoll. Sometimes adding an event that we immediately delete can cause unintended consequences: in kqueue,this makes pending events get reported spuriously.
//不使用changelist (gdb) bt #0 0x00007ffff78bbcb0 in epoll_ctl () from /lib64/libc.so.6 #1 0x00007ffff7bad965 in epoll_apply_one_change (ch=ch@entry=0x7fffffffe29c, epollop=<optimized out>, base=<optimized out>) at epoll.c:290 #2 0x00007ffff7bae180 in epoll_nochangelist_add (base=<optimized out>, fd=<optimized out>, old=<optimized out>, events=<optimized out>,p=<optimized out>) at epoll.c:392 #3 0x00007ffff7ba6813 in evmap_io_add_ (base=base@entry=0x6022a0, fd=<optimized out>, ev=ev@entry=0x602710) at evmap.c:330 #4 0x00007ffff7ba1b9e in event_add_nolock_ (ev=ev@entry=0x602710, tv=tv@entry=0x0, tv_is_absolute=tv_is_absolute@entry=0) at event.c:2600 #5 0x00007ffff7ba200e in event_add (ev=0x602710, tv=0x0) at event.c:2445 #6 0x0000000000400991 in main () at helloworld.c:32
//使用changelist (gdb) bt #0 event_changelist_add_ (base=0x6022a0, fd=0, old=0, events=2, p=0x6028c0) at evmap.c:857 #1 0x00007ffff7ba5813 in evmap_io_add_ (base=base@entry=0x6022a0, fd=<optimized out>, ev=ev@entry=0x602710) at evmap.c:330 #2 0x00007ffff7ba0b9e in event_add_nolock_ (ev=ev@entry=0x602710, tv=tv@entry=0x0, tv_is_absolute=tv_is_absolute@entry=0) at event.c:2600 #3 0x00007ffff7ba100e in event_add (ev=0x602710, tv=0x0) at event.c:2445 #4 0x0000000000400a62 in main () at helloworld.c:35
(gdb) bt #0 0x00007ffff78adcb0 in epoll_ctl () from /lib64/libc.so.6 #1 0x00007ffff7ba7669 in epoll_apply_one_change (base=0x6022a0, epollop=0x602540, ch=0x6028d0) at epoll.c:290 #2 0x00007ffff7ba7a48 in epoll_apply_changes (base=0x6022a0) at epoll.c:367 #3 0x00007ffff7ba7caa in epoll_dispatch (base=0x6022a0, tv=0x0) at epoll.c:457 #4 0x00007ffff7b9663f in event_base_loop (base=0x6022a0, flags=0) at event.c:1947 #5 0x00007ffff7b95fd3 in event_base_dispatch (event_base=0x6022a0) at event.c:1772 #6 0x0000000000400a6e in main () at hello.c:36
/* 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
Bit 0: close change is add Bit 1: close change is del Bit 2: read change is add Bit 3: read change is del Bit 4: write change is add Bit 5: write change is del Bit 6: old events had EV_READ Bit 7: old events had EV_WRITE Bit 8: old events had EV_CLOSED