Libevent Source Analysis-event processing process

Source: Internet
Author: User

Event Processing Flow

The approximate process for libevent processing time is
1. Set Event_base (i.e. initialize reactor)
2. Setting event events (initializing event)
3. Associating event and Event_base (register event to Event_base)
4. Enter the loop and wait for the event
5. Events occur, handling events.
A UML sequence diagram can be expressed as:

#include <iostream>#include <sys/time.h>#include <event.h>structEvent ev;structTimeval TV;voidTIME_CB (intFd ShortEventvoid* argc) {STD::cout<<"Timer Wakeup"<<STD:: Endl; Event_add (&ev, &AMP;TV);}intMain () {structEvent_base* base=event_base_new (); Tv.tv_sec=Ten; Tv.tv_usec=0; Evtimer_set (&ev, TIME_CB, NULL);//Set Timer eventsEvent_base_set (base, &ev);//Associating event and Event_baseEvent_add (&ev, &AMP;TV);//Register eventEvent_base_dispatch (base);//Enter loop loop, wait for event    return 0;}

First, Event_base was created as reactor, and timer events were set as event. The EV and base are then associated, and the EV is registered with the event dispatcher (Evsel, in event_base). Finally, enter the loop loop and wait for the event to occur.

Check out Event_base_set (base, &ev)

int  event_base_set (struct  event_base *base ,  struct  event  *ev) {/* only innocent events may a Ssigned to a different base */ if  (ev->ev_flags! = evlist_init) //ensure that the event has been initialized  return  (-1    );    _event_debug_assert_is_setup (EV); Ev->ev_base = base ; //set Event_base to event reactor  Ev->ev_pri = base ->nactivequeues/2 ;    //event priority  return  (0 );}  

You can see that this step simply associates the event with the Event_base, which is the reactor in the event where it is stored.

Take a look at Event_add (&ev, &TV)

int event_add(structeventconststruct timeval *tv){    int res;    if (EVUTIL_FAILURE_CHECK(!ev->ev_base)) {        event_warnx("%s: event has no event_base set.", __func__);        return -1;    }    EVBASE_ACQUIRE_LOCK(ev->ev_base, th_base_lock);    0);//这里才是主体部分    EVBASE_RELEASE_LOCK(ev->ev_base, th_base_lock);    return (res);}

Take a look at event_add_internal (EV, TV, 0), omitting part of the code

StaticInlineintEvent_add_internal (struct Event*ev,Const structTimeval *tv,intTv_is_absolute) {structEvent_base *Base= ev->ev_base;intres =0;intnotify =0;if(TV! = NULL &&!) (Ev->ev_flags & Evlist_timeout)) {//TV is not empty and is added to the time heap for time heap expansion        if(Min_heap_reserve (&Base->timeheap,1+ Min_heap_size (&Base-&GT;TIMEHEAP)) = =-1)return(-1);/ * Enomem = = errno * /}/ * If the event is an IO or signal event and the event has been added or activated, insert into the appropriate queue */    if(Ev->ev_events & (ev_read| ev_write| ev_signal)) &&! (Ev->ev_flags & (evlist_inserted| evlist_active)) {if(Ev->ev_events & (ev_read| Ev_write))//io Eventsres = Evmap_io_add (Base, EV-&GT;EV_FD, Ev);//Add to IO event queue        Else if(Ev->ev_events & Ev_signal)//Signal Eventsres = Evmap_signal_add (Base, (int) ev->ev_fd, Ev);//Add to signal event queue        if(Res! =-1) Event_queue_insert (Base, Ev, evlist_inserted);//Insert an event into the queue Base->eventqueue        if(res = =1) {/ * Evmap says we need to notify the main thread. * /notify =1; res =0; }} gettime (Base, &now);//Update time in baseEvent_queue_insert (Base, Ev, evlist_timeout);//Add to timer small Gan    / * If we are not in the right thread, we need to wake up the loop * /    if(Res! =-1&& Notify && Evbase_need_notify (Base))//If the current thread is not a loop thread, wake loop threads. Evthread_notify_base (Base);return(res);}

Finally look at Event_base_dispatch (base);

int event_base_dispatch(struct event_base *event_base){    return0));}

Take a look at Event_base_loop (event_base, 0)

Intevent_base_loop (structEvent_base *Base, int flags) {conststructEventop *evsel =Base->evsel;//Events Dispatcher event Demultiplexer    structTimeval TV;structTimeval *tv_p; int res, Done, retval =0;if(Base->running_loop) {the//loop loop can only be used in the event_base threadEVENT_WARNX ("%s:reentrant invocation. Only one Event_base_loop "            "can run on the event_base at once.", __func__); Evbase_release_lock (Base, Th_base_lock);return-1; }Base->running_loop =1;//Indicates that Even_base is running the loop to prevent other threads from runningClear_time_cache (Base);//Position 0 Tv_cache    if(Base-Sig. ev_signal_added &&Base-Sig. ev_n_signals_added)//If the signal event is setEvsig_set_base (Base);//Set signal_pair[0] bit signal source     Done=0;Base->event_gotterm =Base->event_break =0; while(! Done) {//Enter loop body        Base->event_continue =0; /* Terminate the LoopifWe have been asked to*/if(Base->event_gotterm) {break; }if(Base->event_break) {break; } timeout_correct (Base, &AMP;TV);//Update TimeTv_p = &tv;if(! N_active_callbacks (Base) &&! (Flags & Evloop_nonblock)) {Timeout_next (Base, &tv_p); }Else{            /*             *ifWe have active events, we just pollNewEvents * without waiting.        */Evutil_timerclear (&AMP;TV); }/* If We have no events, we just exit */if(!event_haveevents (Base) &&! N_active_callbacks (Base) {Event_debug ("%s:no events registered.", __func__)); retval =1; Goto Done;//Using a goto? }/* Update last Old time */gettime (Base, &Base-&GT;EVENT_TV); Clear_time_cache (Base); res = Evsel->dispatch (Base, tv_p);//epoll_wait, blocking wait events        if(res = =-1) {Event_debug ("%s:dispatch returned unsuccessfully.", __func__)); retval =-1; Goto Done; } update_time_cache (Base); Timeout_process (Base);//processing to-time events        if(N_active_callbacks (Base) {int n = event_process_active (Base);//Handling events with priority during processing            if(Flags & evloop_once) && n_active_callbacks (Base) ==0&& n! =0) Done=1; }Else if(Flags & Evloop_nonblock) Done=1; } Done:the label used for//gotoClear_time_cache (Base);Base->running_loop =0; Evbase_release_lock (Base, Th_base_lock);return(retval);}

Copyright NOTICE: This article for Bo Master original article, without Bo Master permission not reproduced.

Libevent Source Analysis-event processing process

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.