1 Star 0 Fork 0

caipengxiang/libevent

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
克隆/下载
whatsnew-2.2.txt 14.55 KB
一键复制 编辑 原始数据 按行查看 历史
What's new in Libevent 2.2
Azat Khuzhin
0. Before we start
0.1. About this document
This document describes the key differences between Libevent 2.1 and
Libevent 2.2. It's a work in progress.
For better documentation about libevent, see the links at
http://libevent.org/
Libevent 2.2 would not be possible without the generous help of numerous
contributors. For a list of who did what in Libevent 2.2, please see the
CONTRIBUTORS.md!
0.2. Where to get help
Try looking at the other documentation too. All of the header files have
documentation in the doxygen format; this gets turned into nice HTML and
linked to from the libevent.org website.
You can ask the questions by creating an issue on github.
Note, that the following communication channels had been deprecated:
- #libevent IRC channel at irc.oftc.net
- libevent-users@freehaven.net mailing list
0.3. Compatibility
Our source-compatibility policy is that correct code (that is to say, code
that uses public interfaces of Libevent and relies only on their documented
behavior) should have forward source compatibility: any such code that worked
with a previous version of Libevent should work with this version too.
We don't try to do binary compatibility except within stable release series,
so binaries linked against any version of Libevent 2.1 will probably need to
be recompiled against Libevent 2.2 if you want to use it. It is probable that
we'll break binary compatibility again before Libevent 2.2 is stable.
1. Core New APIs and features
1.1. "Prepare" and "check" watchers
Libevent now has a new mechanism for hooking into the event loop: "prepare" and
"check" watchers. A "prepare" watcher is a callback that fires immediately
before polling for I/O. A "check" watcher is a callback that fires immediately
after polling and before processing any active events. This may be useful for
embedding other libraries' event loops (e.g. UI toolkits) into libevent's. It's
also useful for monitoring server performance. For example, if you measure the
time between "prepare" and "check," that is the polling duration; the difference
between the expected and actual polling duration provides an indication of
kernel scheduling delay. And if you measure the time between "check" and the
next "prepare" (in the next iteration of the event loop), that is a good
approximation of the amount of time handling events; this provides a convenient
way to monitor whether any event handlers are blocking or otherwise performing
heavy computation.
The watcher API is defined in <event2/watch.h>. A concrete example of how
watchers can help monitor server performance is available in
"sample/watch-timing.c".
1.2. Ability to configure read/write buffer sizes for evbuffer/bufferevents
This allows to increase the IO throughtput.
Here is some numbers for the single max read in evbuffer impact:
function client() { becat "$@" | pv > /dev/null; }
function server() { cat /dev/zero | becat -l "$@"; }
Plain bufferevent:
- 40K
$ server -R $((40<<10)) & client -R $((40<<10))
700MiB/s
- 16K *default now*
$ server & client
1.81GiB/s
- 4K
$ server -R $((4<<10)) & client -R $((4<<10))
1.05GiB/s
With OpenSSL (-S):
- 40K *default now*
$ server -S -R $((40<<10)) & client -S -R $((40<<10))
900MiB/s
- 16K *default now*
$ server -S & client -S
745MiB/s
- 4K
$ server -S -R $((4<<10)) & client -S -R $((4<<10))
593MiB/s
So as you can see without openssl 16K is faster then 40K/4K, while for
openssl 40K is still faster then 16K (I guess that this is due to with
openssl SSL_read() more at at time, while with plain we have some
allocations splits in evbuffer and maybe due to some buffer in openssl)
1.3. New backend for windows - wepoll
wepoll is a epoll replacement on windows.
wepoll features, from the official project page [1]:
- Can poll 100000s of sockets efficiently.
- Fully thread-safe.
- Multiple threads can poll the same epoll port.
- Sockets can be added to multiple epoll sets.
- All epoll events (EPOLLIN, EPOLLOUT, EPOLLPRI, EPOLLRDHUP) are supported.
- Level-triggered and one-shot (EPOLLONESTHOT) modes are supported
- Trivial to embed: you need only two files.
[1]: https://github.com/piscisaureus/wepoll
The default backend on Windows is still select, just because it is well
tested, and there is no other reasons. That said, that there is no know
issues with wepoll, so please, use it and report any issues!
1.4. Unix sockets under Windows
Since Windows 10 there is support for unix domain sockets, and Libevent also
supports this, via evutil_socketpair().
1.5. Priority inheritance for pthreads
Now you can use
evthread_use_pthreads_with_flags(EVTHREAD_PTHREAD_PRIO_INHERIT) to use
priority inheritance.
1.6. signalfd support
Linux-specific signal handling backend based on signalfd(2) system call, and
public function event_base_get_signal_method() to obtain an underlying kernel
signal handling mechanism.
2. HTTP New APIs and features
2.1. Support for custom HTTP methods
Libevent HTTP code now supports defining custom HTTP methods. It is done
through a callback:
#define EVHTTP_REQ_CUSTOM ((EVHTTP_REQ_MAX) << 1)
static int ext_method_cb(struct evhttp_ext_method *p)
{
if (p == NULL)
return -1;
if (p->method) {
if (strcmp(p->method, "CUSTOM") == 0) {
p->type = EVHTTP_REQ_CUSTOM;
p->flags = 0; /*EVHTTP_METHOD_HAS_BODY*/
return 0;
}
} else {
if (p->type == EVHTTP_REQ_CUSTOM) {
p->method = "CUSTOM";
return 0;
}
}
}
And to register this callback with http server you can use:
evhttp_set_ext_method_cmp(http, ext_method_cb);
Or registering callback with one client only:
evhttp_connection_set_ext_method_cmp(evcon, ext_method_cb);
2.2. Separate timeouts for read/write/connect phase in HTTP
New API:
- client:
evhttp_connection_set_connect_timeout_tv() -- for connect
evhttp_connection_set_read_timeout_tv() -- for read
evhttp_connection_set_write_timeout_tv() -- for write
- server:
evhttp_set_read_timeout_tv() -- for read
evhttp_set_write_timeout_tv() -- for write
It also changes a logic a little, before there was next fallbacks which
does not handled in new API:
- HTTP_CONNECT_TIMEOUT
- HTTP_WRITE_TIMEOUT
- HTTP_READ_TIMEOUT
And introduce another internal flag (EVHTTP_CON_TIMEOUT_ADJUSTED) that
will be used in evrpc, which adjust evhttp_connection timeout only if it
is not default.
2.3. Add callback support for error pages
Now there is evhttp_set_errorcb(), that could be used to change error pages
of your http server.
This can be used for multi lingual support, or to overcome some browser
limitations (for example Microsoft Internet Explorer may display its own
error pages if ones sent by an HTTP server are smaller than certain sizes)
2.4. Minimal WebSocket server implementation for evhttp
Adds few functions (for more details see event2/ws.h) to use evhttp-based
webserver to handle incoming WebSockets connections. We've tried to use both
libevent and libwebsockets in our application, but found that we need to have
different ports at the same time to handle standard HTTP and WebSockets
traffic. This change can help to stick only with libevent library.
Implementation was inspired by modified Libevent source code in ipush project
[1].
[1]: https://github.com/sqfasd/ipush/tree/master/deps/libevent-2.0.21-stable
Also, WebSocket-based chat server was added as a sample.
2.5. evhttp_bound_set_bevcb()
Like evhttp_set_bevcb(), but for evhttp_bound_socket, and callback of
evhttp_set_bevcb() will not be called if evhttp_bound_set_bevcb() returns
bufferevent.
2.6. evhttp max simultaneous connection limiting
When the max connection limit is enabled and the limit is reached, the server
will respond immediately with 503 Service Unavailable. This can be used to
prevent servers from running out of file descriptors. This is better than
request limiting because clients may make more than one request over a single
connection. Blocking a request does not necessarily close the connection and
free up a socket.
There are two new API:
- evhttp_set_max_connections()
- evhttp_get_connection_count()
2.7. Support for Unix Domain Sockets in evhttp
This can be done using evhttp_connection_base_bufferevent_unix_new()
There are no standard for encoding a unix socket in an url. nginx uses:
http://unix:/path/to/unix/socket:/httppath
The second colon is needed to delimit where the unix path ends and where
the rest of the url continues.
3. Bufferevents
3.1. SSL layer
SSL layer has gained Mbed-TLS support, it is implemented in a different
library - event_mbedtls (remember that for OpenSSL, event_openssl should be
used).
LibreSSL is also supported, but you don't need separate library for this,
since LibreSSL is compatible with OpenSSL.
The library known to work with OpenSSL 3.0 as well, though the performance
with 3.0 is worser.
Some changes in API, the following had been deprecated:
- bufferevent_openssl_get_allow_dirty_shutdown()
- bufferevent_openssl_set_allow_dirty_shutdown()
- bufferevent_mbedtls_get_allow_dirty_shutdown()
- bufferevent_mbedtls_set_allow_dirty_shutdown()
And instead, the following should be used:
- bufferevent_ssl_set_flags()
- bufferevent_ssl_clear_flags()
- bufferevent_ssl_get_flags()
Also there is new flag BUFFEREVENT_SSL_BATCH_WRITE, that allows to avoid
Nagle effect in SSL.
4. DNS layer
4.1. TCP support
Libevent now has support for DNS requests via TCP.
By default, requests are done via UDP. In case truncated response is received
new attempt is done via TCP connection.
2 new macros DNS_QUERY_USEVC and DNS_QUERY_IGNTC had been added to force all
requests to be done via TCP and to disable switch to TCP in case of truncated
responses.
Possibility for DNS server to listen and receive requests on TCP port also
had been added.
Fallback to TCP in case of truncated DNS requests is done automatically.
To imitate the old behaviour macros DNS_QUERY_IGNTC should be used. To
force all DNS requests to be done via TCP one should use the flag
DNS_QUERY_USEVC. Names DNS_QUERY_IGNTC, DNS_QUERY_USEVC were chosen to
imitate similar flags in c-ares and glibc.
4.2. New evdns options
- evdns-udp-size - allows to configure maximum allowed size of UDP DNS
messages
- probe-backoff-factor - backoff factor of probe timeout
- max-probe-timeout - maximum timeout between two probe packets will change
initial-probe-timeout when this value is smaller
And also evdns now can handle CNAME.
4.3. evdns now has ability to not add default nameservers
By default evdns adds "127.0.0.1" if there is no other nameservers.
Two new options had been added:
- DNS_OPTION_NAMESERVERS_NO_DEFAULT
Do not "default" nameserver (i.e. "127.0.0.1:53") if there is no nameservers
in resolv.conf, (iff DNS_OPTION_NAMESERVERS is set)
- EVDNS_BASE_NAMESERVERS_NO_DEFAULT
If EVDNS_BASE_INITIALIZE_NAMESERVERS isset, do not add default
nameserver if there are no nameservers in resolv.conf (just set
DNS_OPTION_NAMESERVERS_NO_DEFAULT internally)
5. Listeners new flags
- LEV_OPT_BIND_IPV6ONLY - bind only to IPv6
- LEV_OPT_BIND_IPV4_AND_IPV6 -- bind to both to IPv4 and IPv6
10. Building
10.1. autotools is deprecated, use cmake
Building with autotools/automake is considiered as deprecated, instead, cmake
is recommended.
CMake is crossplatform so you don't need to support multiple files for
various operation systems, like before.
Libevent has find_package() support, and this is very flexible way of using
the library in your project, since it is very easy to use even local builds
(for more information read more about CMake User Registry).
10.2. Building libevent as a sub-project using GNU Auto* tools
Some projects will choose to include libevent in their source distribution,
and build libevent as a sub-project. This may be effected by putting the
line:
AC_CONFIG_SUBDIRS([path/to/libevent])
in the master configure.ac file for the master project.
There are cases where the master project will want to pass in additional
flags for CFLAGS, CPPFLAGS, or LDFLAGS. Since these variables are reserved
for the user, and AM_CFLAGS, AM_CPPFLAGS, and AM_LDFLAGS are reserved for
each package, libevent offers the following variables for a master package
to tell libevent that there are additional compile/link values:
LIBEVENT_CFLAGS
LIBEVENT_CPPFLAGS
LIBEVENT_LDFLAGS
A master package can set these variables in its configure.ac file.
Here's an example:
configure.ac:
...
EXTRA_CFLAGS=...
EXTRA_CPPFLAGS=...
EXTRA_LDFLAGS=...
...
dnl ac_configure_args is undocumented but widely abused, as here,
dnl to modify the defaults of the libevent subpackage, by prefixing
dnl our changes to the child configure arguments already assembled.
dnl User-supplied contradictory choices should prevail thanks to
dnl "last wins".
ac_configure_args=" --disable-openssl${ac_configure_args}"
ac_configure_args=" --disable-shared${ac_configure_args}"
ac_configure_args=" --disable-libevent-regress${ac_configure_args}"
ac_configure_args=" --disable-libevent-install${ac_configure_args}"
ac_configure_args=" --enable-silent-rules${ac_configure_args}"
ac_configure_args=" --enable-function-sections${ac_configure_args}"
ac_configure_args=" LIBEVENT_CFLAGS='${EXTRA_CFLAGS}'${ac_configure_args}"
ac_configure_args=" LIBEVENT_CPPFLAGS='${EXTRA_CPPFLAGS}'${ac_configure_args}"
ac_configure_args=" LIBEVENT_LDFLAGS='${EXTRA_LDFLAGS}'${ac_configure_args}"
AC_CONFIG_SUBDIRS([libevent])
...
The space after the initial '"' is significant.
11. Continious Integration
Now Libevent uses github actions for CI, previously we had travis-ci for
linux/macos and appveyor for win32 (removed in #951), and also I used testing
vagrant for some time, but it had been moved into a separate repository
(8c1838be). But actually this is not required anymore since github actions
supports:
- linux
- freebsd
- windows
- osx
- openbsd
- and also tests under Thread/Address/Undefind sanitizers
So no need to test something locally before releases.
One thing that worth to mention, now, CI depends on public workers, and they
are pretty limited, so it take some time to run the whole CI.
12. Documentation
Now documentation is automatically deployed to https://libevent.org/doc/
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
1
https://gitee.com/awfeequdng/libevent.git
git@gitee.com:awfeequdng/libevent.git
awfeequdng
libevent
libevent
master

搜索帮助