]> git.llucax.com Git - software/libev.git/blobdiff - ev.3
*** empty log message ***
[software/libev.git] / ev.3
diff --git a/ev.3 b/ev.3
index 6494928f3b14bf9a202f40637ab72c8c6d27d1ff..2129dc3002c1baa745b2640b103da86f35244408 100644 (file)
--- a/ev.3
+++ b/ev.3
@@ -453,15 +453,24 @@ environment variable.
 This is your standard \fIselect\fR\|(2) backend. Not \fIcompletely\fR standard, as
 libev tries to roll its own fd_set with no limits on the number of fds,
 but if that fails, expect a fairly low limit on the number of fds when
 This is your standard \fIselect\fR\|(2) backend. Not \fIcompletely\fR standard, as
 libev tries to roll its own fd_set with no limits on the number of fds,
 but if that fails, expect a fairly low limit on the number of fds when
-using this backend. It doesn't scale too well (O(highest_fd)), but its usually
-the fastest backend for a low number of fds.
+using this backend. It doesn't scale too well (O(highest_fd)), but its
+usually the fastest backend for a low number of (low\-numbered :) fds.
+.Sp
+To get good performance out of this backend you need a high amount of
+parallelity (most of the file descriptors should be busy). If you are
+writing a server, you should \f(CW\*(C`accept ()\*(C'\fR in a loop to accept as many
+connections as possible during one iteration. You might also want to have
+a look at \f(CW\*(C`ev_set_io_collect_interval ()\*(C'\fR to increase the amount of
+readyness notifications you get per iteration.
 .ie n .IP """EVBACKEND_POLL""    (value 2, poll backend, available everywhere except on windows)" 4
 .el .IP "\f(CWEVBACKEND_POLL\fR    (value 2, poll backend, available everywhere except on windows)" 4
 .IX Item "EVBACKEND_POLL    (value 2, poll backend, available everywhere except on windows)"
 .ie n .IP """EVBACKEND_POLL""    (value 2, poll backend, available everywhere except on windows)" 4
 .el .IP "\f(CWEVBACKEND_POLL\fR    (value 2, poll backend, available everywhere except on windows)" 4
 .IX Item "EVBACKEND_POLL    (value 2, poll backend, available everywhere except on windows)"
-And this is your standard \fIpoll\fR\|(2) backend. It's more complicated than
-select, but handles sparse fds better and has no artificial limit on the
-number of fds you can use (except it will slow down considerably with a
-lot of inactive fds). It scales similarly to select, i.e. O(total_fds).
+And this is your standard \fIpoll\fR\|(2) backend. It's more complicated
+than select, but handles sparse fds better and has no artificial
+limit on the number of fds you can use (except it will slow down
+considerably with a lot of inactive fds). It scales similarly to select,
+i.e. O(total_fds). See the entry for \f(CW\*(C`EVBACKEND_SELECT\*(C'\fR, above, for
+performance tips.
 .ie n .IP """EVBACKEND_EPOLL""   (value 4, Linux)" 4
 .el .IP "\f(CWEVBACKEND_EPOLL\fR   (value 4, Linux)" 4
 .IX Item "EVBACKEND_EPOLL   (value 4, Linux)"
 .ie n .IP """EVBACKEND_EPOLL""   (value 4, Linux)" 4
 .el .IP "\f(CWEVBACKEND_EPOLL\fR   (value 4, Linux)" 4
 .IX Item "EVBACKEND_EPOLL   (value 4, Linux)"
@@ -471,7 +480,7 @@ like O(total_fds) where n is the total number of fds (or the highest fd),
 epoll scales either O(1) or O(active_fds). The epoll design has a number
 of shortcomings, such as silently dropping events in some hard-to-detect
 cases and rewiring a syscall per fd change, no fork support and bad
 epoll scales either O(1) or O(active_fds). The epoll design has a number
 of shortcomings, such as silently dropping events in some hard-to-detect
 cases and rewiring a syscall per fd change, no fork support and bad
-support for dup:
+support for dup.
 .Sp
 While stopping, setting and starting an I/O watcher in the same iteration
 will result in some caching, there is still a syscall per such incident
 .Sp
 While stopping, setting and starting an I/O watcher in the same iteration
 will result in some caching, there is still a syscall per such incident
@@ -482,6 +491,13 @@ very well if you register events for both fds.
 Please note that epoll sometimes generates spurious notifications, so you
 need to use non-blocking I/O or other means to avoid blocking when no data
 (or space) is available.
 Please note that epoll sometimes generates spurious notifications, so you
 need to use non-blocking I/O or other means to avoid blocking when no data
 (or space) is available.
+.Sp
+Best performance from this backend is achieved by not unregistering all
+watchers for a file descriptor until it has been closed, if possible, i.e.
+keep at least one watcher active per fd at all times.
+.Sp
+While nominally embeddeble in other event loops, this feature is broken in
+all kernel versions tested so far.
 .ie n .IP """EVBACKEND_KQUEUE""  (value 8, most \s-1BSD\s0 clones)" 4
 .el .IP "\f(CWEVBACKEND_KQUEUE\fR  (value 8, most \s-1BSD\s0 clones)" 4
 .IX Item "EVBACKEND_KQUEUE  (value 8, most BSD clones)"
 .ie n .IP """EVBACKEND_KQUEUE""  (value 8, most \s-1BSD\s0 clones)" 4
 .el .IP "\f(CWEVBACKEND_KQUEUE\fR  (value 8, most \s-1BSD\s0 clones)" 4
 .IX Item "EVBACKEND_KQUEUE  (value 8, most BSD clones)"
@@ -503,10 +519,22 @@ course). While stopping, setting and starting an I/O watcher does never
 cause an extra syscall as with \f(CW\*(C`EVBACKEND_EPOLL\*(C'\fR, it still adds up to
 two event changes per incident, support for \f(CW\*(C`fork ()\*(C'\fR is very bad and it
 drops fds silently in similarly hard-to-detect cases.
 cause an extra syscall as with \f(CW\*(C`EVBACKEND_EPOLL\*(C'\fR, it still adds up to
 two event changes per incident, support for \f(CW\*(C`fork ()\*(C'\fR is very bad and it
 drops fds silently in similarly hard-to-detect cases.
+.Sp
+This backend usually performs well under most conditions.
+.Sp
+While nominally embeddable in other event loops, this doesn't work
+everywhere, so you might need to test for this. And since it is broken
+almost everywhere, you should only use it when you have a lot of sockets
+(for which it usually works), by embedding it into another event loop
+(e.g. \f(CW\*(C`EVBACKEND_SELECT\*(C'\fR or \f(CW\*(C`EVBACKEND_POLL\*(C'\fR) and using it only for
+sockets.
 .ie n .IP """EVBACKEND_DEVPOLL"" (value 16, Solaris 8)" 4
 .el .IP "\f(CWEVBACKEND_DEVPOLL\fR (value 16, Solaris 8)" 4
 .IX Item "EVBACKEND_DEVPOLL (value 16, Solaris 8)"
 .ie n .IP """EVBACKEND_DEVPOLL"" (value 16, Solaris 8)" 4
 .el .IP "\f(CWEVBACKEND_DEVPOLL\fR (value 16, Solaris 8)" 4
 .IX Item "EVBACKEND_DEVPOLL (value 16, Solaris 8)"
-This is not implemented yet (and might never be).
+This is not implemented yet (and might never be, unless you send me an
+implementation). According to reports, \f(CW\*(C`/dev/poll\*(C'\fR only supports sockets
+and is not embeddable, which would limit the usefulness of this backend
+immensely.
 .ie n .IP """EVBACKEND_PORT""    (value 32, Solaris 10)" 4
 .el .IP "\f(CWEVBACKEND_PORT\fR    (value 32, Solaris 10)" 4
 .IX Item "EVBACKEND_PORT    (value 32, Solaris 10)"
 .ie n .IP """EVBACKEND_PORT""    (value 32, Solaris 10)" 4
 .el .IP "\f(CWEVBACKEND_PORT\fR    (value 32, Solaris 10)" 4
 .IX Item "EVBACKEND_PORT    (value 32, Solaris 10)"
@@ -516,12 +544,19 @@ it's really slow, but it still scales very well (O(active_fds)).
 Please note that solaris event ports can deliver a lot of spurious
 notifications, so you need to use non-blocking I/O or other means to avoid
 blocking when no data (or space) is available.
 Please note that solaris event ports can deliver a lot of spurious
 notifications, so you need to use non-blocking I/O or other means to avoid
 blocking when no data (or space) is available.
+.Sp
+While this backend scales well, it requires one system call per active
+file descriptor per loop iteration. For small and medium numbers of file
+descriptors a \*(L"slow\*(R" \f(CW\*(C`EVBACKEND_SELECT\*(C'\fR or \f(CW\*(C`EVBACKEND_POLL\*(C'\fR backend
+might perform better.
 .ie n .IP """EVBACKEND_ALL""" 4
 .el .IP "\f(CWEVBACKEND_ALL\fR" 4
 .IX Item "EVBACKEND_ALL"
 Try all backends (even potentially broken ones that wouldn't be tried
 with \f(CW\*(C`EVFLAG_AUTO\*(C'\fR). Since this is a mask, you can do stuff such as
 \&\f(CW\*(C`EVBACKEND_ALL & ~EVBACKEND_KQUEUE\*(C'\fR.
 .ie n .IP """EVBACKEND_ALL""" 4
 .el .IP "\f(CWEVBACKEND_ALL\fR" 4
 .IX Item "EVBACKEND_ALL"
 Try all backends (even potentially broken ones that wouldn't be tried
 with \f(CW\*(C`EVFLAG_AUTO\*(C'\fR). Since this is a mask, you can do stuff such as
 \&\f(CW\*(C`EVBACKEND_ALL & ~EVBACKEND_KQUEUE\*(C'\fR.
+.Sp
+It is definitely not recommended to use this flag.
 .RE
 .RS 4
 .Sp
 .RE
 .RS 4
 .Sp
@@ -757,7 +792,7 @@ overhead for the actual polling but can deliver many events at once.
 By setting a higher \fIio collect interval\fR you allow libev to spend more
 time collecting I/O events, so you can handle more events per iteration,
 at the cost of increasing latency. Timeouts (both \f(CW\*(C`ev_periodic\*(C'\fR and
 By setting a higher \fIio collect interval\fR you allow libev to spend more
 time collecting I/O events, so you can handle more events per iteration,
 at the cost of increasing latency. Timeouts (both \f(CW\*(C`ev_periodic\*(C'\fR and
-\&\f(CW\*(C`ev_timer\*(C'\fR) will be not affected. Setting this to a non-null bvalue will
+\&\f(CW\*(C`ev_timer\*(C'\fR) will be not affected. Setting this to a non-null value will
 introduce an additional \f(CW\*(C`ev_sleep ()\*(C'\fR call into most loop iterations.
 .Sp
 Likewise, by setting a higher \fItimeout collect interval\fR you allow libev
 introduce an additional \f(CW\*(C`ev_sleep ()\*(C'\fR call into most loop iterations.
 .Sp
 Likewise, by setting a higher \fItimeout collect interval\fR you allow libev