--- libev/ev.pod 2007/12/07 16:44:12 1.67 +++ libev/ev.pod 2007/12/08 03:53:36 1.73 @@ -50,6 +50,10 @@ =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 these event sources and provide your program with events. @@ -734,8 +738,9 @@ 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) @@ -764,6 +769,9 @@ 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 :). @@ -885,7 +893,7 @@ 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). @@ -1742,12 +1750,21 @@ #include -(it is not installed by default). This automatically includes F -and puts all of its definitions (many of them macros) into the global -namespace. All C++ specific things are put into the C namespace. - -It should support all the same embedding options as F, most notably -C. +This automatically includes F and puts all of its definitions (many +of them macros) into the global namespace. All C++ specific things are +put into the C namespace. It should support all the same embedding +options as F, most notably C. + +Care has been taken to keep the overhead low. The only data member the C++ +classes add (compared to plain C-style watchers) is the event loop pointer +that the watcher is associated with (or no additional members at all if +you disable C when embedding libev). + +Currently, functions, and static and non-static member functions can be +used as callbacks. Other types should be easy to add as long as they only +need one additional pointer for context. If you need support for other +types of functors please contact the author (preferably after implementing +it). Here is a list of things available in the C namespace: @@ -1773,20 +1790,58 @@ =over 4 -=item ev::TYPE::TYPE (object *, object::method *) +=item ev::TYPE::TYPE () -=item ev::TYPE::TYPE (object *, object::method *, struct ev_loop *) +=item ev::TYPE::TYPE (struct ev_loop *) =item ev::TYPE::~TYPE -The constructor takes a pointer to an object and a method pointer to -the event handler callback to call in this class. The constructor calls -C for you, which means you have to call the C method -before starting it. If you do not specify a loop then the constructor -automatically associates the default loop with this watcher. +The constructor (optionally) takes an event loop to associate the watcher +with. If it is omitted, it will use C. + +The constructor calls C for you, which means you have to call the +C method before starting it. + +It will not set a callback, however: You have to call the templated C +method to set a callback before you can start the watcher. + +(The reason why you have to use a method is a limitation in C++ which does +not allow explicit template arguments for constructors). The destructor automatically stops the watcher if it is active. +=item w->set (object *) + +This method sets the callback method to call. The method has to have a +signature of C, it receives the watcher as +first argument and the C as second. The object must be given as +parameter and is stored in the C member of the watcher. + +This method synthesizes efficient thunking code to call your method from +the C callback that libev requires. If your compiler can inline your +callback (i.e. it is visible to it at the place of the C call and +your compiler is good :), then the method will be fully inlined into the +thunking function, making it as fast as a direct C callback. + +Example: simple class declaration and watcher initialisation + + struct myclass + { + void io_cb (ev::io &w, int revents) { } + } + + myclass obj; + ev::io iow; + iow.set (&obj); + +=item w->set (void (*function)(watcher &w, int), void *data = 0) + +Also sets a callback, but uses a static method or plain function as +callback. The optional C argument will be stored in the watcher's +C member and is free for you to use. + +See the method-C above for more details. + =item w->set (struct ev_loop *) Associates a different C with this watcher. You can only @@ -1795,13 +1850,14 @@ =item w->set ([args]) Basically the same as C, with the same args. Must be -called at least once. Unlike the C counterpart, an active watcher gets -automatically stopped and restarted. +called at least once. Unlike the C counterpart, an active watcher gets +automatically stopped and restarted when reconfiguring it with this +method. =item w->start () -Starts the watcher. Note that there is no C argument as the -constructor already takes the loop. +Starts the watcher. Note that there is no C argument, as the +constructor already stores the event loop. =item w->stop () @@ -1836,9 +1892,10 @@ } myclass::myclass (int fd) - : io (this, &myclass::io_cb), - idle (this, &myclass::idle_cb) { + io .set (this); + idle.set (this); + io.start (fd, ev::READ); } @@ -1846,7 +1903,7 @@ =head1 MACRO MAGIC Libev can be compiled with a variety of options, the most fundemantal is -C. This option determines wether (most) functions and +C. This option determines whether (most) functions and callbacks have an initial C argument. To make it easier to write programs that cope with either variant, the @@ -1890,7 +1947,7 @@ =back Example: Declare and initialise a check watcher, utilising the above -macros so it will work regardless of wether multiple loops are supported +macros so it will work regardless of whether multiple loops are supported or not. static void @@ -2125,6 +2182,23 @@ 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 @@ -2236,24 +2310,51 @@ 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