Epoll efficient mechanism is actually the kernel callback, we know that Linux socket is also treated as file, but the underlying driver is not the same.
Let's take a look at the kernel file structure:
struct File_operations {
struct module *owner;
loff_t (*llseek) (struct file *, loff_t, int);
ssize_t (*read) (struct file *, char *, size_t, loff_t *);
ssize_t (*write) (struct file *, const char *, size_t, loff_t *);
Int (*readdir) (struct file *, void *, filldir_t);
unsigned int (*poll) (struct file *, struct poll_table_struct *);
Int (*ioctl) (struct inode *, struct file *, unsigned int, unsigned long);
You can see that there is a poll function in the structure, which is implemented by the driver, and its core function is:
static inline void poll_wait (struct file * Filp, wait_queue_head_t * wait_address, poll_table *p)
{
if (P && Amp wait_address)
P->qproc (Filp, wait_address, p);
}
Polltable is not actually a table, it is a structure:
typedef void (*POLL_QUEUE_PROC) (struct file *, wait_queue_head_t *, struct poll_table_struct *);
typedef struct POLL_TABLE_STRUCT {
poll_queue_proc qproc;
} poll_table;
Contains a callback function that invokes the callback when the event is driven. Thus, the Epoll kernel implementation can be divided into two layers: the business layer and the driving layer. The business layer implements the functions of the Epoll and adds the new files to the drive layer, and the driver layer notifies the business layer when the event is implemented. The business layer has two functions interacting with the driver layer: Set Queue function A, asynchronous callback function B
Poll_table pt;
Pt.qproc = A;
When a new file is SOCKT1, it is called
Tfile->f_op->poll (Socket1, &pt);
A call now, a is responsible for creating a queue element that contains the asynchronous callback function B and inserts the element into the drive-level queue. When there is an event in the drive layer, the b,b is recalled and the corresponding Socket1 is inserted into the notification list, which is removed by the epoll_wait. In this way, Epoll's core implementation is clear, hope to help everyone.