eventpoll是什么?
eventpoll是一个可以监听多个file发生改变,并调用这个file发生改变的回调函数的一种功能,它一个wait可以wait所有注册到这个eventpoll的文件的改动。
eventpoll框架
一个eventpoll会有很多个epitem,这些epitem会用eventpoll.rbr rbtree组织起来。一个epitem代表eventpoll所监视的一个文件的变动。
1. 被监视文件注册到eventpoll
当一个文件注册到eventpoll时,会创建一个epitem,epitem结构体里的event成员代表此file变动的事件,ep成员指向eventpoll结构体。然后会调用被监视的文件的poll函数,此poll函数再调用poll_wait,调用poll_wait()会给出一个wait_address,这个wait_address是一个wait_queue_head_t,之后会创建一个eppoll_entry,并把eppoll_entry.wait成员加入wait_address所表示的wait queue,并指定了wait callback函数为ep_poll_callback()
2. 在eventpoll.wq上等待wake事件发生/将发生event的被监测的文件的epoll_event put to user
2.1 调用epoll_wait()系统调用将创建一个wait_queue_entry,并将它加入eventpoll.wq,此时指定的wait callback func是default_wake_function,在eventpoll.wq上没有event发生的条件下将会把自己sched out,等eventpoll.wq上有event了,调用wait callback default_wake_function,这个函数就是将前面因为sched out而sleep的线程wakeup;
2.2 eventpoll.wq被wakeup后,从eventpoll.rdllist中取出epitem,此rdllist表示发生了event的被监视的文件链表。取出epitem后,调用这个epitem对应的被监测的文件的poll函数,如果此函数的返回值和epitem.event.events相与值不为0,则将此相与的结果(表示事件类型)以及epitem.event.data put user
3. 被监测的文件产生事件将1中的wait queue wake up
当被监测的文件产生事件时,将1中的wait queue wake up,所以会调用ep_poll_callback(),这个函数得到此发生事件的被监测文件对应的epitem,然后将此epitem.rdllink插入到eventpoll.rdllist,然后将2中的eventpoll.wq wake up
以一个实例来说明,android init进程的fd 4是一个eventpoll anon file,有3个file注册到此eventpoll了,fd分别为6、7、8,6是一个signalfd anon file,7是一个socket file,8是/proc/1/mounts
console:/proc/1 # cat fdinfo/4
pos: 0
flags: 02000002
mnt_id: 13
tfd: 7 events: 19 data: 7f8a2a9130 pos:0 ino:4ab sdev:9
tfd: 6 events: 19 data: 7f8a2a90d0 pos:0 ino:21f9 sdev:d
tfd: 8 events: 1a data: 7f8a2a9190 pos:4122 ino:3043 sdev:4
lrwx------ 1 root root 64 2021-10-29 09:48 4 -> anon_inode:[eventpoll] lrwx------ 1 root root 64 2021-10-29 09:48 5 -> socket:[1194] lrwx------ 1 root root 64 2021-10-29 09:48 6 -> anon_inode:[signalfd] lrwx------ 1 root root 64 2021-10-29 09:48 7 -> socket:[1195] lr-x------ 1 root root 64 2021-10-29 09:48 8 -> /proc/1/mounts