Browse Source

*** empty log message ***

master
Marc Alexander Lehmann 1 year ago
parent
commit
2ed18eef20
4 changed files with 75 additions and 25 deletions
  1. +1
    -0
      Changes
  2. +65
    -16
      ev.3
  3. +8
    -8
      ev.c
  4. +1
    -1
      ev.pod

+ 1
- 0
Changes View File

@ -5,6 +5,7 @@ Revision history for libev, a high-performance and full-featured event loop.
- updated/extended ev_set_allocator documentation.
- replaced EMPTY2 macro by array_needsize_noinit.
- minor code cleanups.
- epoll backend now uses epoll_create1 also after fork.
4.25 Fri Dec 21 07:49:20 CET 2018
- INCOMPATIBLE CHANGE: EV_THROW was renamed to EV_NOEXCEPT


+ 65
- 16
ev.3 View File

@ -133,7 +133,7 @@
.\" ========================================================================
.\"
.IX Title "LIBEV 3"
.TH LIBEV 3 "2019-06-20" "libev-4.25" "libev - high performance full featured event loop"
.TH LIBEV 3 "2019-06-22" "libev-4.25" "libev - high performance full featured event loop"
.\" For nroff, turn off justification. Always turn off hyphenation; it makes
.\" way too many mistakes in technical documents.
.if n .ad l
@ -242,10 +242,10 @@ details of the event, and then hand it over to libev by \fIstarting\fR the
watcher.
.SS "\s-1FEATURES\s0"
.IX Subsection "FEATURES"
Libev supports \f(CW\*(C`select\*(C'\fR, \f(CW\*(C`poll\*(C'\fR, the Linux-specific \f(CW\*(C`epoll\*(C'\fR, the
BSD-specific \f(CW\*(C`kqueue\*(C'\fR and the Solaris-specific event port mechanisms
for file descriptor events (\f(CW\*(C`ev_io\*(C'\fR), the Linux \f(CW\*(C`inotify\*(C'\fR interface
(for \f(CW\*(C`ev_stat\*(C'\fR), Linux eventfd/signalfd (for faster and cleaner
Libev supports \f(CW\*(C`select\*(C'\fR, \f(CW\*(C`poll\*(C'\fR, the Linux-specific aio and \f(CW\*(C`epoll\*(C'\fR
interfaces, the BSD-specific \f(CW\*(C`kqueue\*(C'\fR and the Solaris-specific event port
mechanisms for file descriptor events (\f(CW\*(C`ev_io\*(C'\fR), the Linux \f(CW\*(C`inotify\*(C'\fR
interface (for \f(CW\*(C`ev_stat\*(C'\fR), Linux eventfd/signalfd (for faster and cleaner
inter-thread wakeup (\f(CW\*(C`ev_async\*(C'\fR)/signal handling (\f(CW\*(C`ev_signal\*(C'\fR)) relative
timers (\f(CW\*(C`ev_timer\*(C'\fR), absolute timers with customised rescheduling
(\f(CW\*(C`ev_periodic\*(C'\fR), synchronous signals (\f(CW\*(C`ev_signal\*(C'\fR), process status
@ -696,7 +696,40 @@ faster than epoll for maybe up to a hundred file descriptors, depending on
the usage. So sad.
.Sp
While nominally embeddable in other event loops, this feature is broken in
all kernel versions tested so far.
a lot of kernel revisions, but probably(!) works in current versions.
.Sp
This backend maps \f(CW\*(C`EV_READ\*(C'\fR and \f(CW\*(C`EV_WRITE\*(C'\fR in the same way as
\&\f(CW\*(C`EVBACKEND_POLL\*(C'\fR.
.ie n .IP """EVBACKEND_LINUXAIO"" (value 64, Linux)" 4
.el .IP "\f(CWEVBACKEND_LINUXAIO\fR (value 64, Linux)" 4
.IX Item "EVBACKEND_LINUXAIO (value 64, Linux)"
Use the linux-specific linux aio (\fInot\fR \f(CWaio(7)\fR) event interface
available in post\-4.18 kernels.
.Sp
If this backend works for you (as of this writing, it was very
experimental and only supports a subset of file types), it is the best
event interface available on linux and might be well worth it enabling it
\&\- if it isn't available in your kernel this will be detected and another
backend will be chosen.
.Sp
This backend can batch oneshot requests and uses a user-space ring buffer
to receive events. It also doesn't suffer from most of the design problems
of epoll (such as not being able to remove event sources from the epoll
set), and generally sounds too good to be true. Because, this being the
linux kernel, of course it suffers from a whole new set of limitations.
.Sp
For one, it is not easily embeddable (but probably could be done using
an event fd at some extra overhead). It also is subject to various
arbitrary limits that can be configured in \fI/proc/sys/fs/aio\-max\-nr\fR
and \fI/proc/sys/fs/aio\-nr\fR), which could lead to it being skipped during
initialisation.
.Sp
Most problematic in practise, however, is that, like kqueue, it requires
special support from drivers, and, not surprisingly, not all drivers
implement it. For example, in linux 4.19, tcp sockets, pipes, event fds,
files, \fI/dev/null\fR and a few others are supported, but ttys are not, so
this is not (yet?) a generic event polling interface but is probably still
be very useful in a web server or similar program.
.Sp
This backend maps \f(CW\*(C`EV_READ\*(C'\fR and \f(CW\*(C`EV_WRITE\*(C'\fR in the same way as
\&\f(CW\*(C`EVBACKEND_POLL\*(C'\fR.
@ -810,6 +843,14 @@ used if available.
.Vb 1
\& struct ev_loop *loop = ev_loop_new (ev_recommended_backends () | EVBACKEND_KQUEUE);
.Ve
.Sp
Example: Similarly, on linux, you mgiht want to take advantage of the
linux aio backend if possible, but fall back to something else if that
isn't available.
.Sp
.Vb 1
\& struct ev_loop *loop = ev_loop_new (ev_recommended_backends () | EVBACKEND_LINUXAIO);
.Ve
.RE
.IP "ev_loop_destroy (loop)" 4
.IX Item "ev_loop_destroy (loop)"
@ -1750,13 +1791,13 @@ But really, best use non-blocking mode.
\fIThe special problem of disappearing file descriptors\fR
.IX Subsection "The special problem of disappearing file descriptors"
.PP
Some backends (e.g. kqueue, epoll) need to be told about closing a file
descriptor (either due to calling \f(CW\*(C`close\*(C'\fR explicitly or any other means,
such as \f(CW\*(C`dup2\*(C'\fR). The reason is that you register interest in some file
descriptor, but when it goes away, the operating system will silently drop
this interest. If another file descriptor with the same number then is
registered with libev, there is no efficient way to see that this is, in
fact, a different file descriptor.
Some backends (e.g. kqueue, epoll, linuxaio) need to be told about closing
a file descriptor (either due to calling \f(CW\*(C`close\*(C'\fR explicitly or any other
means, such as \f(CW\*(C`dup2\*(C'\fR). The reason is that you register interest in some
file descriptor, but when it goes away, the operating system will silently
drop this interest. If another file descriptor with the same number then
is registered with libev, there is no efficient way to see that this is,
in fact, a different file descriptor.
.PP
To avoid having to explicitly tell libev about such cases, libev follows
the following policy: Each time \f(CW\*(C`ev_io_set\*(C'\fR is being called, libev
@ -1818,9 +1859,10 @@ reuse the same code path.
\fIThe special problem of fork\fR
.IX Subsection "The special problem of fork"
.PP
Some backends (epoll, kqueue) do not support \f(CW\*(C`fork ()\*(C'\fR at all or exhibit
useless behaviour. Libev fully supports fork, but needs to be told about
it in the child if you want to continue to use it in the child.
Some backends (epoll, kqueue, probably linuxaio) do not support \f(CW\*(C`fork ()\*(C'\fR
at all or exhibit useless behaviour. Libev fully supports fork, but needs
to be told about it in the child if you want to continue to use it in the
child.
.PP
To support fork in your child processes, you have to call \f(CW\*(C`ev_loop_fork
()\*(C'\fR after a fork in the child, enable \f(CW\*(C`EVFLAG_FORKCHECK\*(C'\fR, or resort to
@ -4569,6 +4611,7 @@ in your include path (e.g. in libev/ when using \-Ilibev):
\& ev_select.c only when select backend is enabled
\& ev_poll.c only when poll backend is enabled
\& ev_epoll.c only when the epoll backend is enabled
\& ev_linuxaio.c only when the linux aio backend is enabled
\& ev_kqueue.c only when the kqueue backend is enabled
\& ev_port.c only when the solaris port backend is enabled
.Ve
@ -4759,6 +4802,12 @@ If defined to be \f(CW1\fR, libev will compile in support for the Linux
otherwise another method will be used as fallback. This is the preferred
backend for GNU/Linux systems. If undefined, it will be enabled if the
headers indicate GNU/Linux + Glibc 2.4 or newer, otherwise disabled.
.IP "\s-1EV_USE_LINUXAIO\s0" 4
.IX Item "EV_USE_LINUXAIO"
If defined to be \f(CW1\fR, libev will compile in support for the Linux
aio backend. Due to it's currenbt limitations it has to be requested
explicitly. If undefined, it will be enabled on linux, otherwise
disabled.
.IP "\s-1EV_USE_KQUEUE\s0" 4
.IX Item "EV_USE_KQUEUE"
If defined to be \f(CW1\fR, libev will compile in support for the \s-1BSD\s0 style


+ 8
- 8
ev.c View File

@ -400,10 +400,6 @@
# define EV_USE_POLL 0
#endif
#if EV_USE_LINUXAIO
# include <linux/aio_abi.h> /* probably only needed for aio_context_t */
#endif
/* on linux, we can use a (slow) syscall to avoid a dependency on pthread, */
/* which makes programs even slower. might work on other unices, too. */
#if EV_USE_CLOCK_SYSCALL
@ -444,7 +440,7 @@
#if EV_USE_LINUXAIO
# include <sys/syscall.h>
# if !SYS_io_getevents
# if !SYS_io_getevents || !EV_USE_EPOLL
# undef EV_USE_LINUXAIO
# define EV_USE_LINUXAIO 0
# endif
@ -1609,6 +1605,10 @@ static EV_ATOMIC_T have_monotonic; /* did clock_gettime (CLOCK_MONOTONIC) work?
/*****************************************************************************/
#if EV_USE_LINUXAIO
# include <linux/aio_abi.h> /* probably only needed for aio_context_t */
#endif
/* define a suitable floor function (only used by periodics atm) */
#if EV_USE_FLOOR
@ -2735,12 +2735,12 @@ childcb (EV_P_ ev_signal *sw, int revents)
#if EV_USE_KQUEUE
# include "ev_kqueue.c"
#endif
#if EV_USE_LINUXAIO
# include "ev_linuxaio.c"
#endif
#if EV_USE_EPOLL
# include "ev_epoll.c"
#endif
#if EV_USE_LINUXAIO
# include "ev_linuxaio.c"
#endif
#if EV_USE_POLL
# include "ev_poll.c"
#endif


+ 1
- 1
ev.pod View File

@ -606,7 +606,7 @@ interface.
To work around this latter problem, the current version of libev uses
epoll as a fallback for file deescriptor types that do not work. Epoll
is used in, kind of, slow mode that hopefully avoids most of its design
problems.
problems and requires 1-3 extra syscalls per active fd every iteration.
This backend maps C<EV_READ> and C<EV_WRITE> in the same way as
C<EVBACKEND_POLL>.


Loading…
Cancel
Save