Libevent's original intention is to design a cross-platform lightweight i/0 framework, because of historical problems, I/O multiplexing mechanism of each platform is difficult to unify. Therefore, this part of the process of cross-platform approach is worth focusing attention.
The eventop is defined in the source code as follows:
static const struct Eventop * eventops[] = {
#ifdef Have_event_ports
&evportops,
#endif
....
}
This shows that Libevent uses macros to find available reuse mechanisms at compile time.
The order is also a big article. The official documentation describes the multiplexing mechanisms supported in Libevent/dev/poll, Kqueue (2), Event ports, select (2), poll (2) and Epoll (4).
Libevent developers use the benchmarking of the various mechanisms to select the reuse mechanism in terms of high performance to low priority order as shown in the figure:
It can also be understood that the different platform mechanism is not unified. Standard poll and select are difficult to meet the needs of large-scale architecture, specific reference to Dan Kegel's "The c10k Problem" documentation.
As for the adoption of the mechanism, Libevent adopts the method of function pointer.
struct Eventop {
const char *name; /* Mechanism Name * *
void * (*init) (struct event_base *); /* Initialization Event/*
Int (*add) (void *, struct event *); /* Add Event/*
Int (*del) (void *, struct event *); /* Delete Event * *
Int (*dispatch) (struct event_base *, void *, struct timeval *)/* Dispatch Event * *
void (*dealloc) (struct event_base *, void *);/* Releasing Resources/
int need_reinit;
} ;
Each eventop corresponds to an IO multiplexing mechanism in which each function pointer points to a method that uses the mechanism to manipulate the event.
For example, the corresponding EPOLL eventop structure:
1.void * (*init) (...) The function pointer corresponds to a static void * Epoll_init (...)
2. In Epoll_init (), the environment variable is first detected and Null is returned immediately when no epoll mechanism is found.
3. Use Epoll_create (32000) to specify that the maximum number of connections is 32,000, and then allocate the resources required for each member of the Epollop.
4. Finally call the libevent itself's signal initialization function.
The process of selecting and initializing a mechanism is simple:
for (i = 0; Eventops[i] &&! Base-> evbase i + +) {
Base->evsel = Eventops[i];
Base->evbase = Base->evsel->init (base);
}
Traversing the eventops array of the storage mechanism, attempts to initialize sequentially, and a mechanism that is successfully initialized immediately jumps out of the loop. Of course, the detection system environment available mechanism, choose which mechanism is more appropriate, specific reuse mechanism how to use, all these trivial details you need not care, use, as long as the call Event_init () function. Libevent's ingenious encapsulation of a variety of reuse mechanisms avoids the frustration of the mechanism selection when developers develop large-scale architectures and processes across platforms.