]> rtime.felk.cvut.cz Git - sojka/libev.git/blobdiff - ev_kqueue.c
*** empty log message ***
[sojka/libev.git] / ev_kqueue.c
index bc4ac48b30550aabedea0049038b444145e1ba20..9faf65a660676867f4cb81eded3420193f9d923f 100644 (file)
@@ -155,7 +155,8 @@ kqueue_poll (EV_P_ ev_tstamp timeout)
 int inline_size
 kqueue_init (EV_P_ int flags)
 {
-  /* Initialize the kernel queue */
+  /* initialize the kernel queue */
+  kqueue_fd_pid = getpid ();
   if ((backend_fd = kqueue ()) < 0)
     return 0;
 
@@ -185,8 +186,20 @@ kqueue_destroy (EV_P)
 void inline_size
 kqueue_fork (EV_P)
 {
-  close (backend_fd);
-
+  /* some BSD kernels don't just destroy the kqueue itself,
+   * but also close the fd, which isn't documented, and
+   * impossible to support properly.
+   * we remember the pid of the kqueue call and only close
+   * the fd if the pid is still the same.
+   * this leaks fds on sane kernels, but BSD interfaces are
+   * notoriously buggy and rarely get fixed.
+   */
+  pid_t newpid = getpid ();
+
+  if (newpid == kqueue_fd_pid)
+    close (backend_fd);
+
+  kqueue_fd_pid = newpid;
   while ((backend_fd = kqueue ()) < 0)
     ev_syserr ("(libev) kqueue");