You need to assign one or more event_base structures before using the Libevent function. Each event_base structure holds an event collection that can be instrumented to determine which event is active.
If you set event_base to use locks, you can access it securely across multiple threads. However, its event loop can only run on one thread. If you need to detect IO with multiple threads, you need to use a event_base for each thread.
TIP: [Future versions of Libevent may have event_bases support for running multiple thread events. ]
Each event_base has a "method", or backend, that detects which events are ready. The methods that can be identified are:
L Select
L Poll
L Epoll
L Kqueue
L Devpoll
L Evport
L Win32
Users can use environment variables to prohibit certain backend. For example, to prevent kqueue back-end, you can set the EVENT_NOKQUEUE environment variable. If you want to disable the backend in a programmatic way, see the following instructions for Event_config_avoid_method (). 1 Establish the default event_base
The Event_base_new () function assigns and returns a new event_base with default settings. The function detects the environment variable and returns a pointer to the event_base. If an error occurs, NULL is returned. When you select a variety of methods, the function selects the fastest method supported by the OS.
Interface
struct event_base *event_base_new (void);
Most programs use this function enough.
Event_base_new () function declaration in <event2/event.h>, first appeared in Libevent 1.4.3 version.
2 Creating a complex event_base
To have more control over what type of event_base you get, you need to use Event_config. Event_config is an opaque structure that accommodates event_base configuration information. When Event_base is required, the Event_config is passed to Event_base_new_with_config ().
2.1 Interface
struct event_config *event_config_new (void);
struct event_base *event_base_new_with_config (conststruct event_config *cfg);
void event_config_free (struct event_config *cfg);
To assign event_base using these functions, first call Event_config_new () to assign a event_config. Then, call other functions on the event_config and set the desired event_base characteristics. Finally, call Event_base_new_with_config () to get the new event_base. After completing the work, use Event_config_free () to release the Event_config.
2.2 Interface
int event_config_avoid_method (structconstchar *method);
enum event_method_feature {
Ev_feature_et = 0x01,
Ev_feature_o1 = 0x02,
Ev_feature_fds = 0x04,
};
int event_config_require_features (struct event_config *cfg,
enum event_method_feature feature);
enum Event_base_config_flag {
Event_base_flag_nolock = 0x01,
Event_base_flag_ignore_env = 0x02,
EVENT_BASE_FLAG_STARTUP_IOCP = 0x04,
Event_base_flag_no_cache_time = 0x08,
};
int event_config_set_flag (struct event_config *cfg,
enum event_base_config_flag flag);
Calling Event_config_avoid_method () allows libevent to avoid using a specific, available backend by name. Calling Event_config_require_feature () lets libevent not use the backend that does not provide all of the specified characteristics. Calling Event_config_set_flag () lets libevent set one or more run-time flags that will be described below when creating the event_base.
Event_config_require_features () identifiable eigenvalues are:
U ev_feature_et: Requires support for edge-triggered backend.
U ev_feature_o1: Requires adding, removing individual events, or determining which event activates an O (1) complexity back end.
U Ev_feature_fds: Requires support for arbitrary file descriptors, not just the backend of sockets.
The Event_config_set_flag () recognized option values are:
Ø event_base_flag_nolock: Do not assign locks to event_base. Setting this option can save a bit of time for event_base to lock and unlock, but it is not safe to access event_base in multiple threads.
Ø event_base_flag_ignore_env: Do not detect event_* environment variables when you choose to use the back end. You need to think twice about using this flag: it makes it more difficult for users to debug your program's interaction with Libevent.
Ø EVENT_BASE_FLAG_STARTUP_IOCP: for Windows only, allow Libevent to enable any required IOCP distribution logic at startup, rather than on demand.
Ø event_base_flag_no_cache_time: Instead of detecting the current time every time the event loop is ready to execute a time-out callback, it is detected after each timeout callback. Note: This will consume more CPU time.
Ø event_base_flag_epoll_use_changelist: tell Libevent that if you decide to use the Epoll back end, you can safely use a faster changelist based backend. The Epoll-changelist backend can avoid unnecessary system calls between the back-end distribution function calls, and the same FD modifies its state multiple times. However, passing any FD that uses DUP () or its variant clones to the Libevent,epoll-changelist backend triggers a kernel bug that causes incorrect results. This flag is not effective without using the epoll back end. You can also open the Epoll-changelist option by setting the EVENT_EPOLL_USE_CHANGELIST environment variable.
The functions described above Event_config return 0 on success, and return 1 when they fail.
Attention
It is easy to set the Event_config to request a backend that the OS cannot provide. For example, for Libevent 2.0.1-alpha, there is no O (1) backend in Windows, and there is no backend for both Ev_feature_fds and Ev_feature_o1 features in Linux. If you create a configuration that libevent cannot meet, event_base_new_with_config () returns NULL.
2.3 Interface
int event_config_set_num_cpus_hint (structint CPUs);
This function is currently useful only when using IOCP on Windows, although it may be useful in the future on other platforms. This function tells Event_config that you should try to use a given number of CPUs when generating multithreaded event_base. Note that this is just a hint: Event_base may use less CPU than you choose.
Sample
struct event_config *cfg;
struct event_base *base;
int i;
/* My program wants to use edge-triggered events if in all possible. So
I ' ll try to get a base twice:once insisting on edge-triggered IO, and
Once not. */
for (i=0; i<2; ++i) {
CFG = Event_config_new ();
/* I don ' t like select. */
Event_config_avoid_method (CFG, "select");
if (i = = 0)
Event_config_require_features (CFG, ev_feature_et);
Base = Event_base_new_with_config (CFG);
Event_config_free (CFG);
if (base)
break;
/* If We are here, Event_base_new_with_config () returned NULL. If
This is the around the loop, we'll try again without
Setting Ev_feature_et. If the second time around the
Loop, we ' ll give up. */
}
These functions and types are declared in <event2/event.h>.
The EVENT_BASE_FLAG_IGNORE_ENV flag appears for the first time in the 2.0.2-alpha version. The Event_config_set_num_cpus_hint () function is newly introduced in the 2.0.7-RC version. The other contents of this section appear for the first time in the 2.0.1-alpha version. 3 Check the Event_base back-end method
Sometimes you need to check which features event_base supports, or which method you are currently using.
3.1 Interface
Const Char **event_get_supported_methods (void);
The Event_get_supported_methods () function returns a pointer to an array of method names supported by Libevent. The last element of this array is null.
Sample
int i;
Const char **methods = Event_get_supported_methods ();
printf ("Starting Libevent%s. Available methods are:/n ",
Event_get_version ());
for (i=0; methods[i]!= NULL; ++i) {
printf ("%s/n", Methods[i]);
}
Attention
This function returns a list of methods that Libevent is compiled to support. However, when Libevent is running, the operating system may not support all methods. For example, there may be too many bugs in the OS X version of Kqueue that cannot be used.
3.2 Interface
Const Char *event_base_get_method (conststruct event_base *base);
enum event_method_feature event_base_get_features (conststruct event_base *base);
Event_base_get_method () returns the method that Event_base is using. Event_base_get_features () returns the bit mask for the feature supported by the Event_base.
Sample
struct event_base *base;
enum event_method_feature F;
Base = Event_base_new ();
if (!base) {
Puts ("couldn ' t get a event_base!");
Else {
printf ("Using Libevent with backend method%s.",
Event_base_get_method (base));
F = event_base_get_features (base);
if ((F & Ev_feature_et))
printf ("edge-triggered events are supported.");
if ((F & Ev_feature_o1))
printf ("O (1) event notification is supported.");
if ((F & Ev_feature_fds))
printf ("All FD types are supported.");
Puts ("");
}
This function is defined in <event2/event.h>. Event_base_get_method () first appeared in version 1.4.3, and the other functions first appeared in the 2.0.1-alpha version. 4 Release Event_base
After you use Event_base, use Event_base_free () to release it.
Interface
void event_base_free (struct event_base *base);
Note: This function does not release any current events associated with the Event_base, either close their sockets or release any pointers.
Event_base_free () is defined in <event2/event.h>, first implemented by Libevent 1.2. 5 Setting the Event_base priority
Libevent supports setting multiple priority levels for events. However, Event_base only supports a single priority by default. You can call Event_base_priority_init () to set the event_base number of priorities.
Interface
int event_base_priority_init (struct
int n_priorities);
When successful, this function returns 0 and returns 1 when it fails. Base is the number of priority event_base,n_priorities to be modified, which is at least 1. The priority available for each new event will be from 0 (highest) to N_priorities-1 (lowest).
The constant event_max_priorities represents the upper bound of the n_priorities. It is wrong to give a larger value to n_priorities when calling this function.
Attention
This function must be called before any event activation, preferably immediately after the event_base is created.
Sample
For examples, see the event_priority_set documentation.
By default, events associated with Event_base are initialized to have priority N_PRIORITIES/2. The Event_base_priority_init () function is defined in <event2/event.h> and is available from Libevent version 1.0. 6 Reinitialize the event_base after fork ()
Not all event backend can work correctly after calling fork (). Therefore, if you want to continue using event_base in a new process after you start a new process using fork () or other related system calls, you need to reinitialize it.
Interface
int event_reinit (struct event_base *base);
When successful, this function returns 0 and returns 1 when it fails.