summaryrefslogtreecommitdiffstats
path: root/libev/ev_kqueue.c
diff options
context:
space:
mode:
Diffstat (limited to 'libev/ev_kqueue.c')
-rw-r--r--libev/ev_kqueue.c24
1 files changed, 20 insertions, 4 deletions
diff --git a/libev/ev_kqueue.c b/libev/ev_kqueue.c
index 91b85ed..27def23 100644
--- a/libev/ev_kqueue.c
+++ b/libev/ev_kqueue.c
@@ -1,7 +1,7 @@
/*
* libev kqueue backend
*
- * Copyright (c) 2007,2008,2009,2010,2011 Marc Alexander Lehmann <libev@schmorp.de>
+ * Copyright (c) 2007,2008,2009,2010,2011,2012,2013 Marc Alexander Lehmann <libev@schmorp.de>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modifica-
@@ -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");
@@ -196,3 +209,6 @@ kqueue_fork (EV_P)
fd_rearm_all (EV_A);
}
+/* sys/event.h defines EV_ERROR */
+#undef EV_ERROR
+