]> git.llucax.com Git - software/libev.git/commitdiff
implement EVFLAG_FORKCHECK
authorroot <root>
Thu, 29 Nov 2007 17:28:13 +0000 (17:28 +0000)
committerroot <root>
Thu, 29 Nov 2007 17:28:13 +0000 (17:28 +0000)
ev.3
ev.c
ev.h
ev.html
ev.pod
ev_vars.h
ev_wrap.h

diff --git a/ev.3 b/ev.3
index d7652a33708660beed4bf047c10095607be6c564..cf2a42d0ed588cb64e1f7f687915fa6518f5fdc5 100644 (file)
--- 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 1f2429cb184b9684f510a6e7fa59efefd0696cd7..35180023c603d60532c1f2008223a822a8ecdc47 100644 (file)
--- 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 d9f558ab34b2806d8a379371701a761e839d7b6c..ad9bb8eca11ddd890219f8775b1f6bae2f1319a3 100644 (file)
--- 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 08d84d503be9ec99115e53b7e457ca85ce37aa6d..5ca899a0082268c765534da782cac3ade6d99324 100644 (file)
--- a/ev.html
+++ b/ev.html
@@ -6,7 +6,7 @@
        <meta name="description" content="Pod documentation for libev" />
        <meta name="inputfile" content="&lt;standard input&gt;" />
        <meta name="outputfile" content="&lt;standard output&gt;" />
-       <meta name="created" content="Thu Nov 29 13:21:20 2007" />
+       <meta name="created" content="Thu Nov 29 18:28:02 2007" />
        <meta name="generator" content="Pod::Xhtml 1.57" />
 <link rel="stylesheet" href="http://res.tst.eu/pod.css"/></head>
 <body>
@@ -327,6 +327,23 @@ or setgid) then libev will <i>not</i> 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.</p>
+                               </dd>
+                               <dt><code>EVFLAG_FORKCHECK</code></dt>
+                               <dd>
+                                       <p>Instead of calling <code>ev_default_fork</code> or <code>ev_loop_fork</code> manually after
+a fork, you can also make libev check for a fork in each iteration by
+enabling this flag.</p>
+                                       <p>This works by calling <code>getpid ()</code> 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, <code>getpid</code> is actually a simple 5-insn sequence
+without a syscall and thus <i>very</i> fast, but my Linux system also has
+<code>pthread_atfork</code> which is even faster).</p>
+                                       <p>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.</p>
+                                       <p>This flag setting cannot be overriden or specified in the <code>LIBEV_FLAGS</code>
+environment variable.</p>
                                </dd>
                                <dt><code>EVBACKEND_SELECT</code>  (value 1, portable select backend)</dt>
                                <dd>
diff --git a/ev.pod b/ev.pod
index 1e0234c854bdd466b0a78b712a89617eef178826..b1a5fe5e63c83d2ec57a2a7924e2299ee8fef5c3 100644 (file)
--- a/ev.pod
+++ b/ev.pod
@@ -268,6 +268,26 @@ 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.
 
+=item C<EVFLAG_FORKCHECK>
+
+Instead of calling C<ev_default_fork> or C<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 C<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, C<getpid> is actually a simple 5-insn sequence
+without a syscall and thus I<very> fast, but my Linux system also has
+C<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 C<LIBEV_FLAGS>
+environment variable.
+
 =item C<EVBACKEND_SELECT>  (value 1, portable select backend)
 
 This is your standard select(2) backend. Not I<completely> standard, as
index c93d23a0884d249bc51b120b6f717a242fbabab8..6b0c3e98e0c5add0fc2dc4f35515fd434597af82 100644 (file)
--- a/ev_vars.h
+++ b/ev_vars.h
@@ -4,14 +4,18 @@ VARx(ev_tstamp, now_floor) /* last time we refreshed rt_time */
 VARx(ev_tstamp, mn_now)    /* monotonic clock "now" */
 VARx(ev_tstamp, rtmn_diff) /* difference realtime - monotonic time */
 VARx(int, backend)
+VARx(int, activecnt) /* total number of active events ("refcount") */
 
 VARx(ev_tstamp, backend_fudge) /* assumed typical timer resolution */
 VAR (backend_modify, void (*backend_modify)(EV_P_ int fd, int oev, int nev))
 VAR (backend_poll  , void (*backend_poll)(EV_P_ ev_tstamp timeout))
 VARx(int, backend_fd)
 
+#if !defined(_WIN32) || EV_GENWRAP
+VARx(pid_t, curpid)
+#endif
+
 VARx(int, postfork)  /* true if we need to recreate kernel state after fork */
-VARx(int, activecnt) /* total number of active events ("refcount") */
 
 #if EV_USE_SELECT || EV_GENWRAP
 VARx(void *, vec_ri)
index 67e7cfdaaad23fdde88cad7240c49a87634c964b..c0d9ce0f31a6fd9a1830c0f3a5a906beb9c9dfc6 100644 (file)
--- a/ev_wrap.h
+++ b/ev_wrap.h
@@ -3,12 +3,13 @@
 #define mn_now ((loop)->mn_now)
 #define rtmn_diff ((loop)->rtmn_diff)
 #define backend ((loop)->backend)
+#define activecnt ((loop)->activecnt)
 #define backend_fudge ((loop)->backend_fudge)
 #define backend_modify ((loop)->backend_modify)
 #define backend_poll ((loop)->backend_poll)
 #define backend_fd ((loop)->backend_fd)
+#define curpid ((loop)->curpid)
 #define postfork ((loop)->postfork)
-#define activecnt ((loop)->activecnt)
 #define vec_ri ((loop)->vec_ri)
 #define vec_ro ((loop)->vec_ro)
 #define vec_wi ((loop)->vec_wi)