【文章內(nèi)容簡介】
). If it returns zero when memory needs to be allocated (size != 0), the library might abort or take some potentially destructive action.Since some systems (at least OpenBSD and Darwin) fail to implement correct realloc semantics, libev will use a wrapper around the system realloc and free functions by default.You could override this function in highavailability programs to, say, free some memory if it cannot allocate memory, to use a special allocator, or even to sleep a while and retry until some memory is available.Example: Replace the libev allocator with one that waits a bit and then retries (example requires a standardspliant realloc). static void * persistent_realloc (void *ptr, size_t size) { for (。) { void *newptr = realloc (ptr, size)。 if (newptr) return newptr。 sleep (60)。 } } ... ev_set_allocator (persistent_realloc)。ev_set_syserr_cb (void (*cb)(const char *msg)) Set the callback function to call on a retryable system call error (such as failed select, poll, epoll_wait). The message is a printable string indicating the system call or subsystem causing the problem. If this callback is set, then libev will expect it to remedy the situation, no matter what, when it returns. That is, libev will generally retry the requested operation, or, if the condition doesn39。t go away, do bad stuff (such as abort).Example: This is basically the same thing that libev does internally, too. static void fatal_error (const char *msg) { perror (msg)。 abort ()。 } ... ev_set_syserr_cb (fatal_error)。ev_feed_signal (int signum) This function can be used to simulate a signal receive. It is pletely safe to call this function at any time, from any context, including signal handlers or random threads.Its main use is to customise signal handling in your process, especially in the presence of threads. For example, you could block signals by default in all threads (and specifying EVFLAG_NOSIGMASK when creating any loops), and in one thread, use sigwait or any other mechanism to wait for signals, then deliver them to libev by calling ev_feed_signal.FUNCTIONS CONTROLLING EVENT LOOPSAn event loop is described by a struct ev_loop * (the struct is not optional in this case unless libev 3 patibility is disabled, as libev 3 had an ev_loop function colliding with the struct name).The library knows two types of such loops, the default loop, which supports child process events, and dynamically created event loops which do not.struct ev_loop *ev_default_loop (unsigned int flags) This returns the default event loop object, which is what you should normally use when you just need the event loop. Event loop objects and the flags parameter are described in more detail in the entry for ev_loop_new.If the default loop is already initialised then this function simply returns it (and ignores the flags. If that is troubling you, check ev_backend () afterwards). Otherwise it will create it with the given flags, which should almost always be 0, unless the caller is also the one calling ev_run or otherwise qualifies as the main program.If you don39。t know what event loop to use, use the one returned from this function (or via the EV_DEFAULT macro).Note that this function is not threadsafe, so if you want to use it from multiple threads, you have to employ some kind of mutex (note also that this case is unlikely, as loops cannot be shared easily between threads anyway).The default loop is the only loop that can handle ev_child watchers, and to do this, it always registers a handler for SIGCHLD. If this is a problem for your application you can either create a dynamic loop with ev_loop_new which doesn39。t do that, or you can simply overwrite the SIGCHLD signal handler after calling ev_default_init.Example: This is the most typical usage. if (!ev_default_loop (0)) fatal (could not initialise libev, bad $LIBEV_FLAGS in environment?)。Example: Restrict libev to the select and poll backends, and do not allow environment settings to be taken into account: ev_default_loop (EVBACKEND_POLL | EVBACKEND_SELECT | EVFLAG_NOENV)。struct ev_loop *ev_loop_new (unsigned int flags) This will create and initialise a new event loop object. If the loop could not be initialised, returns false.This function is threadsafe, and one mon way to use libev with threads is indeed to create one loop per thread, and using the default loop in the main or initial thread.The flags argument can be used to specify special behaviour or specific backends to use, and is usually specified as 0 (or EVFLAG_AUTO).The following flags are supported:EVFLAG_AUTO The default flags value. Use this if you have no clue (it39。s the right thing, believe me).EVFLAG_NOENV If this flag bit is or39。ed into the flag value (or the program runs setuid or setgid) then libev will not look at the environment variable LIBEV_FLAGS. Otherwise (the default), this environment variable will override the flags pletely if it is found in the environment. This is useful to try out specific backends to test their performance, or to work around bugs.EVFLAG_FORKCHECK Instead of calling ev_loop_fork manually after a fork, you can also make libev check for a fork in each iteration by enabling this flag.This works by calling getpid () on every iteration of the loop, and thus this might slow down your event loop if you do a lot of loop iterations and little real work, but is usually not noticeable (on my GNU/Linux system for example, getpid is actually a simple 5insn sequence without a system call and thus very fast, but my GNU/Linux system also has pthread_atfork which is even faster).The big advantage of this flag is that you can forget about fork (and forget about forgetting to tell libev about forking) when you use this flag.This flag setting cannot be overridden or specified in the LIBEV_FLAGS e