X-Git-Url: https://git.llucax.com/software/libev.git/blobdiff_plain/e71f3fb02d5da3553fc8e80eed84394b962b118f..91c2e643914a5e26e943053c60055bb839204d38:/ev.pod diff --git a/ev.pod b/ev.pod index 70858ce..26b1288 100644 --- a/ev.pod +++ b/ev.pod @@ -6,10 +6,56 @@ libev - a high performance full-featured event loop written in C #include +=head1 EXAMPLE PROGRAM + + #include + + ev_io stdin_watcher; + ev_timer timeout_watcher; + + /* called when data readable on stdin */ + static void + stdin_cb (EV_P_ struct ev_io *w, int revents) + { + /* puts ("stdin ready"); */ + ev_io_stop (EV_A_ w); /* just a syntax example */ + ev_unloop (EV_A_ EVUNLOOP_ALL); /* leave all loop calls */ + } + + static void + timeout_cb (EV_P_ struct ev_timer *w, int revents) + { + /* puts ("timeout"); */ + ev_unloop (EV_A_ EVUNLOOP_ONE); /* leave one loop call */ + } + + int + main (void) + { + struct ev_loop *loop = ev_default_loop (0); + + /* initialise an io watcher, then start it */ + ev_io_init (&stdin_watcher, stdin_cb, /*STDIN_FILENO*/ 0, EV_READ); + ev_io_start (loop, &stdin_watcher); + + /* simple non-repeating 5.5 second timeout */ + ev_timer_init (&timeout_watcher, timeout_cb, 5.5, 0.); + ev_timer_start (loop, &timeout_watcher); + + /* loop till timeout or data ready */ + ev_loop (loop, 0); + + return 0; + } + =head1 DESCRIPTION +The newest version of this document is also available as a html-formatted +web page you might find easier to navigate when reading it for the first +time: L. + Libev is an event loop: you register interest in certain events (such as a -file descriptor being readable or a timeout occuring), and it will manage +file descriptor being readable or a timeout occurring), and it will manage these event sources and provide your program with events. To do this, it must take more or less complete control over your process @@ -23,23 +69,29 @@ watcher. =head1 FEATURES -Libev supports select, poll, the linux-specific epoll and the bsd-specific -kqueue mechanisms for file descriptor events, relative timers, absolute -timers with customised rescheduling, signal events, process status change -events (related to SIGCHLD), and event watchers dealing with the event -loop mechanism itself (idle, prepare and check watchers). It also is quite -fast (see this L comparing -it to libevent for example). +Libev supports C(2) backend. No attempt at autodetection will be done: if no +other method takes over, select will be it. Otherwise the select backend +will not be compiled in. + +=item EV_SELECT_USE_FD_SET + +If defined to C<1>, then the select backend will use the system C +structure. This is useful if libev doesn't compile due to a missing +C or C definition or it misguesses the bitset layout on +exotic systems. This usually limits the range of file descriptors to some +low limit such as 1024 or might have other limitations (winsocket only +allows 64 sockets). The C macro, set before compilation, might +influence the size of the C used. + +=item EV_SELECT_IS_WINSOCKET + +When defined to C<1>, the select backend will assume that +select/socket/connect etc. don't understand file descriptors but +wants osf handles on win32 (this is the case when the select to +be used is the winsock select). This means that it will call +C<_get_osfhandle> on the fd to convert it to an OS handle. Otherwise, +it is assumed that all these functions actually work on fds, even +on win32. Should not be defined on non-win32 platforms. + +=item EV_USE_POLL + +If defined to be C<1>, libev will compile in support for the C(2) +backend. Otherwise it will be enabled on non-win32 platforms. It +takes precedence over select. + +=item EV_USE_EPOLL + +If defined to be C<1>, libev will compile in support for the Linux +C(7) backend. Its availability will be detected at runtime, +otherwise another method will be used as fallback. This is the +preferred backend for GNU/Linux systems. + +=item EV_USE_KQUEUE + +If defined to be C<1>, libev will compile in support for the BSD style +C(2) backend. Its actual availability will be detected at runtime, +otherwise another method will be used as fallback. This is the preferred +backend for BSD and BSD-like systems, although on most BSDs kqueue only +supports some types of fds correctly (the only platform we found that +supports ptys for example was NetBSD), so kqueue might be compiled in, but +not be used unless explicitly requested. The best way to use it is to find +out whether kqueue supports your type of fd properly and use an embedded +kqueue loop. + +=item EV_USE_PORT + +If defined to be C<1>, libev will compile in support for the Solaris +10 port style backend. Its availability will be detected at runtime, +otherwise another method will be used as fallback. This is the preferred +backend for Solaris 10 systems. + +=item EV_USE_DEVPOLL + +reserved for future expansion, works like the USE symbols above. + +=item EV_USE_INOTIFY + +If defined to be C<1>, libev will compile in support for the Linux inotify +interface to speed up C watchers. Its actual availability will +be detected at runtime. + +=item EV_H + +The name of the F header file used to include it. The default if +undefined is C<< >> in F and C<"ev.h"> in F. This +can be used to virtually rename the F header file in case of conflicts. + +=item EV_CONFIG_H + +If C isn't C<1>, this variable can be used to override +F's idea of where to find the F file, similarly to +C, above. + +=item EV_EVENT_H + +Similarly to C, this macro can be used to override F's idea +of how the F header can be found. + +=item EV_PROTOTYPES + +If defined to be C<0>, then F will not define any function +prototypes, but still define all the structs and other symbols. This is +occasionally useful if you want to provide your own wrapper functions +around libev functions. + +=item EV_MULTIPLICITY + +If undefined or defined to C<1>, then all event-loop-specific functions +will have the C as first argument, and you can create +additional independent event loops. Otherwise there will be no support +for multiple event loops and there is no first event loop pointer +argument. Instead, all functions act on the single default loop. + +=item EV_MINPRI + +=item EV_MAXPRI + +The range of allowed priorities. C must be smaller or equal to +C, but otherwise there are no non-obvious limitations. You can +provide for more priorities by overriding those symbols (usually defined +to be C<-2> and C<2>, respectively). + +When doing priority-based operations, libev usually has to linearly search +all the priorities, so having many of them (hundreds) uses a lot of space +and time, so using the defaults of five priorities (-2 .. +2) is usually +fine. + +If your embedding app does not need any priorities, defining these both to +C<0> will save some memory and cpu. + +=item EV_PERIODIC_ENABLE + +If undefined or defined to be C<1>, then periodic timers are supported. If +defined to be C<0>, then they are not. Disabling them saves a few kB of +code. + +=item EV_IDLE_ENABLE + +If undefined or defined to be C<1>, then idle watchers are supported. If +defined to be C<0>, then they are not. Disabling them saves a few kB of +code. + +=item EV_EMBED_ENABLE + +If undefined or defined to be C<1>, then embed watchers are supported. If +defined to be C<0>, then they are not. + +=item EV_STAT_ENABLE + +If undefined or defined to be C<1>, then stat watchers are supported. If +defined to be C<0>, then they are not. + +=item EV_FORK_ENABLE + +If undefined or defined to be C<1>, then fork watchers are supported. If +defined to be C<0>, then they are not. + +=item EV_MINIMAL + +If you need to shave off some kilobytes of code at the expense of some +speed, define this symbol to C<1>. Currently only used for gcc to override +some inlining decisions, saves roughly 30% codesize of amd64. + +=item EV_PID_HASHSIZE + +C watchers use a small hash table to distribute workload by +pid. The default size is C<16> (or C<1> with C), usually more +than enough. If you need to manage thousands of children you might want to +increase this value (I be a power of two). + +=item EV_INOTIFY_HASHSIZE + +C watchers use a small hash table to distribute workload by +inotify watch id. The default size is C<16> (or C<1> with C), +usually more than enough. If you need to manage thousands of C +watchers you might want to increase this value (I be a power of +two). + +=item EV_COMMON + +By default, all watchers have a C member. By redefining +this macro to a something else you can include more and other types of +members. You have to define it each time you include one of the files, +though, and it must be identical each time. + +For example, the perl EV module uses something like this: + + #define EV_COMMON \ + SV *self; /* contains this struct */ \ + SV *cb_sv, *fh /* note no trailing ";" */ + +=item EV_CB_DECLARE (type) + +=item EV_CB_INVOKE (watcher, revents) + +=item ev_set_cb (ev, cb) + +Can be used to change the callback member declaration in each watcher, +and the way callbacks are invoked and set. Must expand to a struct member +definition and a statement, respectively. See the F header file for +their default definitions. One possible use for overriding these is to +avoid the C as first argument in all cases, or to use +method calls instead of plain function calls in C++. + +=head2 EXPORTED API SYMBOLS + +If you need to re-export the API (e.g. via a dll) and you need a list of +exported symbols, you can use the provided F files which list +all public symbols, one per line: + + Symbols.ev for libev proper + Symbols.event for the libevent emulation + +This can also be used to rename all public symbols to avoid clashes with +multiple versions of libev linked together (which is obviously bad in +itself, but sometimes it is inconvinient to avoid this). + +A sed command like this will create wrapper C<#define>'s that you need to +include before including F: + + wrap.h + +This would create a file F which essentially looks like this: + + #define ev_backend myprefix_ev_backend + #define ev_check_start myprefix_ev_check_start + #define ev_check_stop myprefix_ev_check_stop + ... + +=head2 EXAMPLES + +For a real-world example of a program the includes libev +verbatim, you can have a look at the EV perl module +(L). It has the libev files in +the F subdirectory and includes them in the F (public +interface) and F (implementation) files. Only the F file +will be compiled. It is pretty complex because it provides its own header +file. + +The usage in rxvt-unicode is simpler. It has a F header file +that everybody includes and which overrides some configure choices: + + #define EV_MINIMAL 1 + #define EV_USE_POLL 0 + #define EV_MULTIPLICITY 0 + #define EV_PERIODIC_ENABLE 0 + #define EV_STAT_ENABLE 0 + #define EV_FORK_ENABLE 0 + #define EV_CONFIG_H + #define EV_MINPRI 0 + #define EV_MAXPRI 0 + + #include "ev++.h" + +And a F implementation file that contains libev proper and is compiled: + + #include "ev_cpp.h" + #include "ev.c" + + +=head1 COMPLEXITIES + +In this section the complexities of (many of) the algorithms used inside +libev will be explained. For complexity discussions about backends see the +documentation for C. + +All of the following are about amortised time: If an array needs to be +extended, libev needs to realloc and move the whole array, but this +happens asymptotically never with higher number of elements, so O(1) might +mean it might do a lengthy realloc operation in rare cases, but on average +it is much faster and asymptotically approaches constant time. + +=over 4 + +=item Starting and stopping timer/periodic watchers: O(log skipped_other_timers) + +This means that, when you have a watcher that triggers in one hour and +there are 100 watchers that would trigger before that then inserting will +have to skip those 100 watchers. + +=item Changing timer/periodic watchers (by autorepeat, again): O(log skipped_other_timers) + +That means that for changing a timer costs less than removing/adding them +as only the relative motion in the event queue has to be paid for. + +=item Starting io/check/prepare/idle/signal/child watchers: O(1) + +These just add the watcher into an array or at the head of a list. +=item Stopping check/prepare/idle watchers: O(1) + +=item Stopping an io/signal/child watcher: O(number_of_watchers_for_this_(fd/signal/pid % EV_PID_HASHSIZE)) + +These watchers are stored in lists then need to be walked to find the +correct watcher to remove. The lists are usually short (you don't usually +have many watchers waiting for the same fd or signal). + +=item Finding the next timer per loop iteration: O(1) + +=item Each change on a file descriptor per loop iteration: O(number_of_watchers_for_this_fd) + +A change means an I/O watcher gets started or stopped, which requires +libev to recalculate its status (and possibly tell the kernel). + +=item Activating one watcher: O(1) + +=item Priority handling: O(number_of_priorities) + +Priorities are implemented by allocating some space for each +priority. When doing priority-based operations, libev usually has to +linearly search all the priorities. + +=back + =head1 AUTHOR