diff --git a/ev.3 b/ev.3 index d7652a3..cf2a42d 100644 --- a/ev.3 +++ b/ev.3 @@ -413,6 +413,26 @@ or setgid) then libev will \fInot\fR look at the environment variable override the flags completely if it is found in the environment. This is useful to try out specific backends to test their performance, or to work around bugs. +.ie n .IP """EVFLAG_FORKCHECK""" 4 +.el .IP "\f(CWEVFLAG_FORKCHECK\fR" 4 +.IX Item "EVFLAG_FORKCHECK" +Instead of calling \f(CW\*(C`ev_default_fork\*(C'\fR or \f(CW\*(C`ev_loop_fork\*(C'\fR manually after +a fork, you can also make libev check for a fork in each iteration by +enabling this flag. +.Sp +This works by calling \f(CW\*(C`getpid ()\*(C'\fR 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 noticable (on my +Linux system for example, \f(CW\*(C`getpid\*(C'\fR is actually a simple 5\-insn sequence +without a syscall and thus \fIvery\fR fast, but my Linux system also has +\&\f(CW\*(C`pthread_atfork\*(C'\fR which is even faster). +.Sp +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. +.Sp +This flag setting cannot be overriden or specified in the \f(CW\*(C`LIBEV_FLAGS\*(C'\fR +environment variable. .ie n .IP """EVBACKEND_SELECT"" (value 1, portable select backend)" 4 .el .IP "\f(CWEVBACKEND_SELECT\fR (value 1, portable select backend)" 4 .IX Item "EVBACKEND_SELECT (value 1, portable select backend)" diff --git a/ev.c b/ev.c index 1f2429c..3518002 100644 --- a/ev.c +++ b/ev.c @@ -906,6 +906,12 @@ loop_init (EV_P_ unsigned int flags) now_floor = mn_now; rtmn_diff = ev_rt_now - mn_now; + /* pid check not overridable via env */ +#ifndef _WIN32 + if (flags & EVFLAG_FORKCHECK) + curpid = getpid (); +#endif + if (!(flags & EVFLAG_NOENV) && !enable_secure () && getenv ("LIBEV_FLAGS")) @@ -1336,8 +1342,19 @@ ev_loop (EV_P_ int flags) ? EVUNLOOP_ONE : EVUNLOOP_CANCEL; + call_pending (EV_A); /* in case we recurse, ensure ordering stays nice and clean */ + while (activecnt) { +#ifndef _WIN32 + if (expect_false (curpid)) /* penalise the forking check even more */ + if (expect_false (getpid () != curpid)) + { + curpid = getpid (); + postfork = 1; + } +#endif + #if EV_FORK_ENABLE /* we might have forked, so queue fork handlers */ if (expect_false (postfork)) diff --git a/ev.h b/ev.h index d9f558a..ad9bb8e 100644 --- a/ev.h +++ b/ev.h @@ -312,6 +312,7 @@ union ev_any_watcher #define EVFLAG_AUTO 0x00000000UL /* not quite a mask */ /* flag bits */ #define EVFLAG_NOENV 0x01000000UL /* do NOT consult environment */ +#define EVFLAG_FORKCHECK 0x02000000UL /* check for a fork in each iteration */ /* method bits to be ored together */ #define EVBACKEND_SELECT 0x00000001UL /* about anywhere */ #define EVBACKEND_POLL 0x00000002UL /* !win */ diff --git a/ev.html b/ev.html index 08d84d5..5ca899a 100644 --- a/ev.html +++ b/ev.html @@ -6,7 +6,7 @@ - +
@@ -327,6 +327,23 @@ or setgid) then libev will not look at the environment variable override the flags completely 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_default_fork
or 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 noticable (on my
+Linux system for example, getpid
is actually a simple 5-insn sequence
+without a syscall and thus very fast, but my 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 overriden or specified in the LIBEV_FLAGS
+environment variable.
EVBACKEND_SELECT
(value 1, portable select backend)