Libevent event-driven, events is the core of his entire library
The role of event: equivalent to the reactor in the framework, it provides a function interface for reactor to be called when an event occurs to perform the appropriate event handling, usually he binds a valid handle
struct Event {tailq_entry (event) (Ev_active_next); Tailq_entry (Event) (ev_next);//int min_heap_idx;
/* for managing timeouts */struct event_base *ev_base;
evutil_socket_t ev_fd;
Union {/* used for IO events */struct {tailq_entry (event) (Ev_io_next);
struct Timeval ev_timeout;
} ev_io;
/* Used by signal events */struct {tailq_entry (event) (Ev_signal_next);
Short Ev_ncalls;
/* allows deletes in callback */short *ev_pncalls;
} ev_signal;
} _ev;
The short ev_events;//is the event type, which mainly includes input and output time, timing time and signal struct timeval ev_timeout; int ev_pri; /* Smaller numbers is higher priority */* allows us to adopt for different types of events */void (*ev_closur
e) (struct event_base *, struct event *);
void (*ev_callback) (evutil_socket_t, short, void *arg);
void *ev_arg; int ev_res; /* Result passed To event callback */int ev_flags; };
Understanding of the structure:
I'm not going to explain to every single one of those obvious or included, I won't say anything.
Whenever an event is turned into a ready state, libevent moves it into active eventlist[priority] (personal understanding is that you can think of event as a node, then there are three lists, one is active, one is signal, One is the input and output, and the Ev_next,ev_active_next and ev_signal_next in the struct are represented in the I/0 event linked list , in the Signal chain list, in the active list, Where priority is the precedence of the event, then Libevent chooses the ready event according to its own scheduling policy, invokes its cb_callback () function to perform event processing, and populates the parameters of the Cb_callback function with the ready handle and Time type
Ev_base is the reactor of the event, after which discussion
EV_FD is a binding file descriptor for I/O events, and for signal time is a binding signal
Ev_callback is the callback function of the event
void (ev_callback) (int fd,short events,void arg);
The FD corresponds to the ev_fd,events corresponding to the ev_events,arg corresponding to the Ev_arg (which is the equivalent of the events stored in this event structure, the corresponding state of the event and the corresponding response of the event).
ev_events;//is the event type that concerns events, including input and output events, timing events, and signals.
EV_PRI: Represents the event priority, the smaller the event is the higher the priority level
Ev_flag: The field that marks the event information, indicating his status
Ev_ncalls: The number of times the ev_callback is called when the event is ready to execute, typically 1
Ev_pncalls: pointer, pointing to ev_ncalls or null (currently does not understand why this is required)
Ev_res: Record the type of event activation
What this structure actually represents is an event.
A function of this struct:
This struct is an event, then there must be a corresponding action to add it to the Libevent .
void Event_set (struct event ev,int fd,short events,void (*callback) (int,short,void), void* Arg)
void
Event_set (struct event *ev, evutil_socket_t FD, short events,
Void (*callback) (evutil_socket_t, short, void *), void *arg)
{
int r;
R = event_assign (EV, Current_base, FD, events, callback, ARG);
Evutil_assert (r = = 0);
}
1. Set the event EV binding file descriptor or signal, set to 1 for timed events
2. Set the event type, such as Ev_read,ev_persist,ev_write,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)
int
event_base_set (struct event_base *base, struct event *ev)
{/* only innocent events ' may '
assigned to a D Ifferent Base */
if (ev->ev_flags! = evlist_init)
return ( -1);
_event_debug_assert_is_setup (EV);
Ev->ev_base = base;
Ev->ev_pri = base->nactivequeues/2;
return (0);
}
Set the event_base that Event_ev will be registered to
Libevent has a global event_base pointer current_base, which is registered to Current_base by default, using this function to specify a different event_base
If there are multiple libevent instances in a process, you must call the function to set a different event_base for the event
int Event_priority_set (struct event* ev,int pri);
int
event_priority_set (struct event *ev, int pri)
{
_event_debug_assert_is_setup (EV);
if (Ev->ev_flags & evlist_active)
return ( -1);
if (pri < 0 | | pri >= ev->ev_base->nactivequeues)
return ( -1);
Ev->ev_pri = pri;
return (0);
}
Setting the priority level