What's New In Libevent 2.0 so far:
1. Meta-issues
1.1. About this document
This document describes the key differences between Libevent 1.4 and
Libevent 2.0, from a user's point of view. It was most recently
updated based on features in git master as of August 2010.
NOTE: I am very sure that I missed some thing on this list. Caveat
haxxor.
1.2. Better documentation
There is now a book-in-progress that explains how to use Libevent and its
growing pile of APIs. As of this writing, it covers everything except the
http and rpc code. Check out the latest draft at
http://www.wangafu.net/~nickm/libevent-book/ .
2. New and Improved Event APIs
Many APIs are improved, refactored, or deprecated in Libevent 2.0.
COMPATIBILITY:
Nearly all existing code that worked with Libevent 1.4 should still
work correctly with Libevent 2.0. However, if you are writing new code,
or if you want to port old code, we strongly recommend using the new APIs
and avoiding deprecated APIs as much as possible.
Binaries linked against Libevent 1.4 will need to be recompiled to link
against Libevent 2.0. This is nothing new; we have never been good at
preserving binary compatibility between releases. We'll try harder in the
future, though: see 2.1 below.
2.1. New header layout for improved forward-compatibility
Libevent 2.0 has a new header layout to make it easier for programmers to
write good, well-supported libevent code. The new headers are divided
into three types.
There are *regular headers*, like event2/event.h. These headers contain
the functions that most programmers will want to use.
There are *backward compatibility headers*, like event2/event_compat.h.
These headers contain declarations for deprecated functions from older
versions of Libevent. Documentation in these headers should suggest what's
wrong with the old functions, and what functions you want to start using
instead of the old ones. Some of these functions might be removed in a
future release. New programs should generally not include these headers.
Finally, there are *structure headers*, like event2/event_struct.h.
These headers contain definitions of some structures that Libevent has
historically exposed. Exposing them caused problems in the past,
since programs that were compiled to work with one version of Libevent
would often stop working with another version that changed the size or
layout of some object. We've moving them into separate headers so
that programmers can know that their code is not depending on any
unstable aspect of the Libvent ABI. New programs should generally not
include these headers unless they really know what they are doing, are
willing to rebuild their software whenever they want to link it
against a new version of Libevent, and are willing to risk their code
breaking if and when data structures change.
Functionality that once was located in event.h is now more subdivided.
The core event logic is now in event2/event.h. The "evbuffer" functions
for low-level buffer manipulation are in event2/buffer.h. The
"bufferevent" functions for higher-level buffered IO are in
event2/bufferevent.h.
COMPATIBILITY:
All of the old headers (event.h, evdns.h, evhttp.h, evrpc.h, and
evutil.h) will continue to work by including the corresponding new
headers. Old code should not be broken by this change.
2.2. New thread-safe, binary-compatible, harder-to-mess-up APIs
Some aspects of the historical Libevent API have encouraged
non-threadsafe code, or forced code built against one version of Libevent
to no longer build with another. The problems with now-deprecated APIs
fell into two categories:
1) Dependence on the "current" event_base. In an application with
multiple event_bases, Libevent previously had a notion of the
"current" event_base. New events were linked to this base, and
the caller needed to explicitly reattach them to another base.
This was horribly error-prone.
Functions like "event_set" that worked with the "current" event_base
are now deprecated but still available (see 2.1). There are new
functions like "event_assign" that take an explicit event_base
argument when setting up a structure. Using these functions will help
prevent errors in your applications, and to be more threadsafe.
2) Structure dependence. Applications needed to allocate 'struct
event' themselves, since there was no function in Libevent to do it
for them. But since the size and contents of struct event can
change between libevent versions, this created binary-compatibility
nightmares. All structures of this kind are now isolated in
_struct.h header (see 2.1), and there are new allocate-and-
initialize functions you can use instead of the old initialize-only
functions. For example, instead of malloc and event_set, you
can use event_new().
(For people who do really want to allocate a struct event on the
stack, or put one inside another structure, you can still use
event2/event_compat.h.)
So in the case where old code would look like this:
#include <event.h>
...
struct event *ev = malloc(sizeof(struct event));
/* This call will cause a buffer overrun if you compile with one version
of Libevent and link dynamically against another. */
event_set(ev, fd, EV_READ, cb, NULL);
/* If you forget this call, your code will break in hard-to-diagnose
ways in the presence of multiple event bases. */
event_set_base(ev, base);
New code will look more like this:
#include <event2/event.h>
...
struct event *ev;
ev = event_new(base, fd, EV_READ, cb, NULL);
2.3. Overrideable allocation functions
If you want to override the allocation functions used by libevent
(for example, to use a specialized allocator, or debug memory
issues, or so on), you can replace them by calling
event_set_mem_functions. It takes replacements for malloc(),
free(), and realloc().
If you're going to use this facility, you need to call it _before_
Libevent does any memory allocation; otherwise, Libevent may allocate some
memory with malloc(), and free it with the free() function you provide.
You can disable this feature when you are building Libevent by passing
the --disable-malloc-replacement argument to configure.
2.4. Configurable event_base creation
Older versions of Libevent would always got the fastest backend
available, unless you reconfigured their behavior with the environment
variables EVENT_NOSELECT, EVENT_NOPOLL, and so forth. This was annoying
to programmers who wanted to pick a backend explicitly without messing
with the environment.
Also, despite our best efforts, not every backend supports every
operation we might like. Some features (like edge-triggered events, or
working with non-socket file descriptors) only work with some operating
systems' fast backends. Previously, programmers who cared about this
needed to know which backends supported what. This tended to get quite
ungainly.
There is now an API to choose backends, either by name or by feature.
Here is an example:
struct event_config_t *config;
struct event_base *base;
/* Create a new configuration object. */
config = event_config_new();
/* We don't want to use the "select" method. */
event_config_avoid_method(config, "select");
/* We want a method that can work with non-socket file descriptors */
event_config_require_features(config, EV_FEATURE_FDS);
base = event_base_new_with_config(config);
if (!base) {
/* There is no backend method that does what we want. */
exit(1);
}
event_config_free(config);
Supported features are documented in event