X-Git-Url: https://git.llucax.com/software/libev.git/blobdiff_plain/756a6378f76a80c595335d4a78ab426cc44d247d..71b44ee4e9677f9ddc2b7f91f32654cfd1bd2f73:/ev.pod?ds=inline diff --git a/ev.pod b/ev.pod index b1a5fe5..6d8fe82 100644 --- a/ev.pod +++ b/ev.pod @@ -6,7 +6,7 @@ libev - a high performance full-featured event loop written in C #include -=head1 EXAMPLE PROGRAM +=head2 EXAMPLE PROGRAM #include @@ -50,8 +50,12 @@ libev - a high performance full-featured event loop written in C =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 @@ -63,7 +67,7 @@ watchers>, which are relatively small C structures you initialise with the details of the event, and then hand it over to libev by I the watcher. -=head1 FEATURES +=head2 FEATURES Libev supports C which have a high +overhead for the actual polling but can deliver many events at once. + +By setting a higher I 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 C and +C) will be not affected. Setting this to a non-null value will +introduce an additional C call into most loop iterations. + +Likewise, by setting a higher I you allow libev +to spend more time collecting timeouts, at the expense of increased +latency (the watcher callback will be called later). C watchers +will not be affected. Setting this to a non-null value will not introduce +any overhead in libev. + +Many (busy) programs can usually benefit by setting the io collect +interval to a value near C<0.1> or so, which is often enough for +interactive servers (of course not for games), likewise for timeouts. It +usually doesn't make much sense to set it to a lower value than C<0.01>, +as this approsaches the timing granularity of most systems. + =back @@ -724,8 +858,9 @@ it. Returns a true value iff the watcher is pending, (i.e. it has outstanding events but its callback has not yet been invoked). As long as a watcher is pending (but not active) you must not call an init function on it (but -C is safe) and you must make sure the watcher is available to -libev (e.g. you cnanot C it). +C is safe), you must not change its priority, and you must +make sure the watcher is available to libev (e.g. you cannot C +it). =item callback ev_cb (ev_TYPE *watcher) @@ -736,6 +871,46 @@ Returns the callback currently set on the watcher. Change the callback. You can change the callback at virtually any time (modulo threads). +=item ev_set_priority (ev_TYPE *watcher, priority) + +=item int ev_priority (ev_TYPE *watcher) + +Set and query the priority of the watcher. The priority is a small +integer between C (default: C<2>) and C +(default: C<-2>). Pending watchers with higher priority will be invoked +before watchers with lower priority, but priority will not keep watchers +from being executed (except for C watchers). + +This means that priorities are I used for ordering callback +invocation after new events have been received. This is useful, for +example, to reduce latency after idling, or more often, to bind two +watchers on the same event and make sure one is called first. + +If you need to suppress invocation when higher priority events are pending +you need to look at C watchers, which provide this functionality. + +You I change the priority of a watcher as long as it is active or +pending. + +The default priority used by watchers when no priority has been set is +always C<0>, which is supposed to not be too high and not be too low :). + +Setting a priority outside the range of C to C is +fine, as long as you do not mind that the priority value you query might +or might not have been adjusted to be within valid range. + +=item ev_invoke (loop, ev_TYPE *watcher, int revents) + +Invoke the C with the given C and C. Neither +C nor C need to be valid as long as the watcher callback +can deal with that fact. + +=item int ev_clear_pending (loop, ev_TYPE *watcher) + +If the watcher is pending, this function returns clears its pending status +and returns its C bitset (as if its callback was invoked). If the +watcher isn't pending it does nothing and returns C<0>. + =back @@ -829,12 +1004,6 @@ fd as you want (as long as you don't confuse yourself). Setting all file descriptors to non-blocking mode is also usually a good idea (but not required if you know what you are doing). -You have to be careful with dup'ed file descriptors, though. Some backends -(the linux epoll backend is a notable example) cannot handle dup'ed file -descriptors correctly if you register interest in two or more fds pointing -to the same underlying file/socket/etc. description (that is, they share -the same underlying "file open"). - If you must do this, then force the use of a known-to-be-good backend (at the time of this writing, this includes only C and C). @@ -850,10 +1019,56 @@ C is far preferable to a program hanging until some data arrives. If you cannot run the fd in non-blocking mode (for example you should not play around with an Xlib connection), then you have to seperately re-test -wether a file descriptor is really ready with a known-to-be good interface +whether a file descriptor is really ready with a known-to-be good interface such as poll (fortunately in our Xlib example, Xlib already does this on its own, so its quite safe to use). +=head3 The special problem of disappearing file descriptors + +Some backends (e.g. kqueue, epoll) need to be told about closing a file +descriptor (either by calling C explicitly or by any other means, +such as C). 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. + +To avoid having to explicitly tell libev about such cases, libev follows +the following policy: Each time C is being called, libev +will assume that this is potentially a new file descriptor, otherwise +it is assumed that the file descriptor stays the same. That means that +you I to call C (or C) when you change the +descriptor even if the file descriptor number itself did not change. + +This is how one would do it normally anyway, the important point is that +the libev application should not optimise around libev but should leave +optimisations to libev. + +=head3 The special problem of dup'ed file descriptors + +Some backends (e.g. epoll), cannot register events for file descriptors, +but only events for the underlying file descriptions. That means when you +have C'ed file descriptors or weirder constellations, and register +events for them, only one file descriptor might actually receive events. + +There is no workaround possible except not registering events +for potentially C'ed file descriptors, or to resort to +C or C. + +=head3 The special problem of fork + +Some backends (epoll, kqueue) do not support C at all or exhibit +useless behaviour. Libev fully supports fork, but needs to be told about +it in the child. + +To support fork in your programs, you either have to call +C or C after a fork in the child, +enable C, or resort to C or +C. + + +=head3 Watcher-Specific Functions + =over 4 =item ev_io_init (ev_io *, callback, int fd, int events) @@ -874,6 +1089,8 @@ The events being watched. =back +=head3 Examples + Example: Call C when STDIN_FILENO has become, well readable, but only once. Since it is likely line-buffered, you could attempt to read a whole line in the callback. @@ -916,6 +1133,8 @@ The callback is guarenteed to be invoked only when its timeout has passed, but if multiple timers become ready during the same loop iteration then order of execution is undefined. +=head3 Watcher-Specific Functions and Data Members + =over 4 =item ev_timer_init (ev_timer *, callback, ev_tstamp after, ev_tstamp repeat) @@ -978,6 +1197,8 @@ which is also when any modifications are taken into account. =back +=head3 Examples + Example: Create a timer that fires after 60 seconds. static void @@ -1020,16 +1241,18 @@ to trigger "at" some specific point in time. For example, if you tell a periodic watcher to trigger in 10 seconds (by specifiying e.g. C) and then reset your system clock to the last year, then it will take a year to trigger the event (unlike an C, which would trigger -roughly 10 seconds later and of course not if you reset your system time -again). +roughly 10 seconds later). They can also be used to implement vastly more complex timers, such as -triggering an event on eahc midnight, local time. +triggering an event on each midnight, local time or other, complicated, +rules. As with timers, the callback is guarenteed to be invoked only when the time (C) has been passed, but if multiple periodic timers become ready during the same loop iteration then order of execution is undefined. +=head3 Watcher-Specific Functions and Data Members + =over 4 =item ev_periodic_init (ev_periodic *, callback, ev_tstamp at, ev_tstamp interval, reschedule_cb) @@ -1041,18 +1264,18 @@ operation, and we will explain them from simplest to complex: =over 4 -=item * absolute timer (interval = reschedule_cb = 0) +=item * absolute timer (at = time, interval = reschedule_cb = 0) In this configuration the watcher triggers an event at the wallclock time C and doesn't repeat. It will not adjust when a time jump occurs, that is, if it is to be run at January 1st 2011 then it will run when the system time reaches or surpasses this time. -=item * non-repeating interval timer (interval > 0, reschedule_cb = 0) +=item * non-repeating interval timer (at = offset, interval > 0, reschedule_cb = 0) In this mode the watcher will always be scheduled to time out at the next -C time (for some integer N) and then repeat, regardless -of any time jumps. +C time (for some integer N, which can also be negative) +and then repeat, regardless of any time jumps. This can be used to create timers that do not drift with respect to system time: @@ -1068,7 +1291,11 @@ Another way to think about it (for the mathematically inclined) is that C will try to run the callback in this mode at the next possible time where C