Libevent source code in-depth analysis 5
-- Core of libevent: Event
Zhang Liang
After having a high-level understanding of the event processing process, this section describes the core structure event of libevent and how libevent manages the event.
1 libevent core-Event
Libevent is based on event-driven. You can see from the name that event is the core of the entire library. Event is the event handler component in the reactor framework. It provides function interfaces for the reactor to call an event to execute corresponding event processing. Generally, it is bound with a valid handle.
First, the declaration of the event struct is given, which is located in the event. h file:
Struct event {<br/> tailq_entry (event) ev_next; <br/> tailq_entry (event) ev_active_next; <br/> tailq_entry (event) ev_signal_next; <br/> unsigned int min_heap_idx;/* for managing timeouts */<br/> struct event_base * ev_base; <br/> int ev_fd; <br/> short ev_events; <br/> short ev_ncils; <br/> short * ev_pncils;/* allows deletes in callback */<br/> struct timeval ev_timeout; <br/> int ev_pri; /* smaller numbers are higher priority */<br/> void (* ev_callback) (INT, short, void * Arg); <br/> void * ev_arg; <br/> int ev_res;/* result passed to Event Callback */<br/> int ev_flags; <br/> };
The following briefly explains the meaning of each field in the struct.
1) ev_events: The Event Type followed by the event. It can be of the following three types:
I/O events: ev_write and ev_read
Scheduled event: ev_timeout
Signal: ev_signal
Auxiliary option: ev_persist, indicating a permanent event
Libevent is defined:
# Define ev_timeout 0x01 <br/> # define ev_read 0x02 <br/> # define ev_write 0x04 <br/> # define ev_signal 0x08 <br/> # define ev_persist 0x10/* persistant event */
We can see that the event type can be combined using the "|" operator. It must be noted that the signal and I/O events cannot be set at the same time;
We can also see that libevent uses the event struct to unify the processing of these three events;
2) ev_next, ev_active_next, and ev_signal_next are two-way linked list node pointers. They are fields used by libevent to manage different event types and events in different periods.
Libevent uses a two-way linked list to store all registered I/O and signal events. ev_next is the position of the I/O event in the linked list. It is called "registered event linked list ";
Similarly, ev_signal_next is the position of the signal event in the signal event linked list;
Ev_active_next: libevent puts all the activation events into the active list of the linked list and traverses the active list for scheduling. ev_active_next indicates the position of the event in the active list;
2) min_heap_idx and ev_timeout. If they are timeout events, they are the index and supervalue of events in the small root heap. libevent uses the small root heap to manage scheduled events, this will be explained in detail during subsequent scheduled event processing.
3) ev_base the reactor instance to which the event belongs. This is an event_base struct. The next section will explain in detail;
4) ev_fd: for I/O events, it is the bound file descriptor; for signal events, it is the bound signal;
5) ev_callback: the callback function of the event, called by ev_base, executes the event processing program. This is a function pointer, prototype:
Void (* ev_callback) (int fd, short events, void * Arg)
The FD parameter corresponds to ev_fd; events corresponds to ev_events; arg corresponds to ev_arg;
6) ev_arg: void * indicates that the data can be of any type and is specified when event is set;
7) eb_flags: libevent is used to mark the event information field, indicating its current status. Possible values include:
# Define evlist_timeout 0x01 // event in time heap <br/> # define evlist_inserted 0x02 // event in the registered event chain table <br/> # define evlist_signal 0x04 // not used <br/> # define evlist_active 0x08 // event in the active linked list <br/> # define evlist_internal 0x10 // internal use Mark <br/> # define evlist_init 0x80 // the event has been initialized.
8) ev_ncils: the number of calls to ev_callback when the event is ready for execution, usually 1;
9) ev_pncils: pointer, usually pointing to ev_ncils or NULL;
10) ev_res: specifies the type of the active event;
2 libevent Event Management
Starting from the three linked list node pointers and a heap index in the event struct, libevent's event management method can also be seen in the following:
Every time an event changes to the ready state, libevent moves it to the active event list [Priority], where priority is the priority of the event;
Then, libevent selects a ready event based on its scheduling policy, calls its cb_callback () function to execute event processing, and fills in the parameters of the cb_callback function according to the ready handle and event type.
3. interface functions set for the event
To add an event to libevent, you must first set the event object. The functions provided by libevent are: event_set (), event_base_set (), event_priority_set; the following sections describe each other.
Void event_set (struct event * eV, int FD, short events,
Void (* callback) (INT, short, void *), void * Arg)
1. Set the file descriptor or signal bound to the event eV. For a scheduled event, set it to-1;
2. Set the event type, such as ev_read | ev_persist, ev_write, and ev_signal;
3. Set the Event Callback Function and the parameter ARG;
4. initialize other fields, such as the default event_base and priority;
Int event_base_set (struct event_base * base, struct event * eV)
Set event_base to be registered by event EV;
Libevent has a global event_base pointer current_base. By default, the event EV will be registered to current_base. You can use this function to specify different event_base;
If a process contains multiple libevent instances, you must call this function to set different event_base for the event;
Int event_priority_set (struct event * eV, int PRI)
There is nothing to say about setting the priority of event eV. Note that when eV is in the ready state and cannot be set,-1 is returned.
4. Summary
This section describes the core event structure of libevent, the event types supported by libevent, and the event management model of libevent. The following describes the libevent event processing framework, and the important struct event_base used in it;