Libevent source code in-depth analysis 7

Source: Internet
Author: User
Libevent source code in-depth analysis 7

-- Event Main Loop
Zhang Liang

Now we have a preliminary understanding of the libevent reactor component -- event_base and the event management framework. Next we will take the main loop of the libevent event processing as the central part, execute an event loop based on the multi-channel event distribution mechanism provided by the system. For registered ready events, call the callback function of the registered event to process the events.

1. Staged victory

Libevent combines I/O events, timers, and signal event processing. This section also describes how libevent achieves this.
After reading the content in this section, you should have a clear understanding of the basic libevent framework: Event Management and the main loop, the libevent event control process can be clearly colluded with each other. The rest is the details.

2 event processing main cycle

The main cycle of libevent events is mainly completed through the event_base_loop () function. The main operations are shown in the flowchart below. What event_base_loop does is to continuously execute the following loop.
 

The main operations of event_base_loop are clear, so you can check the source code. The code structure is quite clear.
Int event_base_loop (struct event_base * base, int flags) <br/>{< br/> const struct eventop * evsel = base-> evsel; <br/> void * evbase = base-> evbase; <br/> struct timeval TV; <br/> struct timeval * TV _p; <br/> int res, done; <br/> // clear time cache <br/> base-> TV _cache. TV _sec = 0; <br/> // evsignal_base is a global variable. When processing signal, used to indicate the event_base instance to which signal belongs <br/> If (base-> Sig. ev_signal_added) <br/> evsignal_base = base; <B R/> done = 0; <br/> while (! Done) {// event main loop <br/> // check whether the loop needs to be jumped out. The program can call event_loopexit_cb () to set the event_gotterm tag <br/> // call event_base_loopbreak () set event_break flag <br/> If (base-> event_gotterm) {<br/> base-> event_gotterm = 0; <br/> break; <br/>}< br/> If (base-> event_break) {<br/> base-> event_break = 0; <br/> break; <br/>}< br/> // calibration system time. If the system uses a non-monotonic time, the user may adjust the system time backwards <br/> // In the timeout_correct function, compare the last wait time and the current time. If The previous time <last wait time <br/> // indicates that the time is incorrect. This is the timeout time for updating all scheduled events in timer_heap. <Br/> timeout_correct (base, & TV); </P> <p> // based on the minimum timeout time of the event in timer heap, maximum wait time of the computing system I/O demultiplexer <br/> TV _p = & TV; <br/> If (! Base-> event_count_active &&! (Flags & evloop_nonblock) {<br/> timeout_next (base, & TV _p); <br/>} else {<br/> // There is still a ready time for unprocessing, let I/O demultiplexer return immediately without waiting <br/> // as mentioned below, in libevent, low-priority readiness events may not be processed immediately <br/> evutil_timerclear (& TV); <br/>}< br/> // if no event is registered yet, exit <br/> If (! Event_haveevents (base) {<br/> event_debug ("% s: no events registered. ", _ FUNC _); <br/> return (1); <br/>}< br/> // update last wait time, and clear the time cache <br/> gettime (base, & base-> event_ TV); <br/> base-> TV _cache. TV _sec = 0; <br/> // call the system I/O demultiplexer to wait for the ready I/O events, which may be epoll_wait, or select; <br/> // In the evsel-> dispatch () the ready signal event and I/O event are inserted into the active linked list. <br/> res = evsel-> dispatch (base, evbase, TV _ P); <br/> If (RES =-1) <br/> return (-1 ); <br/> // assign the time cache value to the current system time <br/> gettime (base, & base-> TV _cache ); <br/> // check the timer events in heap, delete the ready timer event from heap, and insert it to the active linked list. <br/> timeout_process (base ); <br/> // call event_process_active () to process the ready event in the active linked list, call its callback function to execute event processing <br/> // This function searches for the active event linked list with the highest priority (smaller priority value, <br/> // then process all readiness events in the linked list. <br/> // low-priority readiness events may not be processed in a timely manner; <br/> If (base-> event_count _ Active) {<br/> event_process_active (base); <br/> If (! Base-> event_count_active & (flags & evloop_once) <br/> done = 1; <br/>} else if (flags & evloop_nonblock) <br/> done = 1; <br/>}< br/> // loop end, clear time cache <br/> base-> TV _cache. TV _sec = 0; <br/> event_debug ("% s: asked to terminate loop. ", _ FUNC _); <br/> return (0); <br/>}< br/>

3 consistency of I/O and timer events

Libevent unified the timer and signal events to the system's I/O demultiplex mechanism. I believe the readers can also see from the above process and code, I will try again later.
First, Timer events are integrated into the system I/O multiplexing mechanism, which is quite clear because the system's I/O mechanism is like select () and epoll_wait () allow the program to specify a maximum wait time (also known as the maximum timeout time) Timeout. Even if no I/O event occurs, they can be returned within the timeout time.
Set the timeout time of system I/O based on the minimum timeout time of all timer events. When system I/O returns, activate all ready timer events, in this way, Timer events can be perfectly integrated into the system's I/O mechanism.
This is a classic way to process timer events in reactor and proactor modes (active mode, such as iocp on Windows). Ace also uses this method, for details, refer to the reactor mode section in POSA vol2.
Heap is a classic data structure. the time complexity of inserting and deleting elements to the heap is O (lgn), and N is the number of elements in the heap, the complexity of obtaining the minimum key value (small root heap) is O (1). Therefore, it becomes an excellent candidate for managing timer events (of course not unique). libevent is a heap structure.

4 unification of I/O and signal events

Signal is a classic example of asynchronous events. It is not as natural as timer events to unify signal events into system I/O multiplexing, the emergence of the signal event is completely random for the process. The process cannot only test a variable to determine whether a signal has occurred, but must tell the kernel "when this signal occurs, perform the following operations ".
If a signal occurs, instead of calling the callback function of the event to process the signal immediately, it tries to notify the System of the I/O mechanism and let it return, then we can handle the I/O events and timer together. Yes, this is also the method used in libevent.
The core of the problem is how to notify the System of the I/O multiplexing mechanism when signal occurs. Here we will first buy a sub-Customs and then describe it in the Signal Processing Section, I think readers can also come up with a notification method, such as using pipe.

Section 5

This section describes the main cycle of libevent events, describes how libevent handles ready I/O events, timers, and signal events, and how to seamlessly integrate them together.
Come on!

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.