summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRoy Marples <roy@marples.name>2021-01-30 01:37:15 +0000
committerRoy Marples <roy@marples.name>2021-01-30 01:37:15 +0000
commitd747ef075ce1c9795f0a6975a1e74672166d5b21 (patch)
treeaaaf9499f16c96e1c8f49b7011bdf68d65cfe90a
parente11849f8e2d0d93bd02fac9f296e3c99ff102e32 (diff)
downloaddhcpcd-d747ef075ce1c9795f0a6975a1e74672166d5b21.tar.xz
eloop: Default to using ppoll(2) again.
Even though we now have fully working kqueue(2) and epoll(7) with our privsep code, ppoll(2) is faster and smaller for our workload. This time though, we will keep the code here as it's fully working and while fixing kqueue we also fixed other bugs in dhcpcd as a result so it's not time wasted at all.
-rwxr-xr-xconfigure58
-rw-r--r--src/eloop.c25
2 files changed, 25 insertions, 58 deletions
diff --git a/configure b/configure
index 091815ab..07360a52 100755
--- a/configure
+++ b/configure
@@ -1221,61 +1221,9 @@ fi
# Set this for eloop
echo "#define HAVE_REALLOCARRAY" >>$CONFIG_H
-if [ -z "$POLL" ]; then
- printf "Testing for kqueue1 ... "
- cat <<EOF >_kqueue1.c
-#include <sys/event.h>
-#include <sys/fcntl.h>
-#include <sys/time.h>
-int main(void) {
- return kqueue1(O_CLOEXEC);
-}
-EOF
- if $XCC _kqueue1.c -o _kqueue1 2>&3; then
- POLL=kqueue1
- echo "yes"
- else
- echo "no"
- fi
- rm -f _kqueue1.c _kqueue1
-fi
-
-if [ -z "$POLL" ]; then
- printf "Testing for kqueue ... "
- cat <<EOF >_kqueue.c
-#include <sys/types.h>
-#include <sys/event.h>
-#include <sys/time.h>
-int main(void) {
- return kqueue();
-}
-EOF
- if $XCC _kqueue.c -o _kqueue 2>&3; then
- POLL=kqueue
- echo "yes"
- else
- echo "no"
- fi
- rm -f _kqueue.c _kqueue
-fi
-
-if [ -z "$POLL" ]; then
- printf "Testing for epoll ... "
- cat <<EOF >_epoll.c
-#include <sys/epoll.h>
-int main(void) {
- return epoll_create1(EPOLL_CLOEXEC);
-}
-EOF
- if $XCC _epoll.c -o _epoll 2>&3; then
- POLL=epoll
- echo "yes"
- else
- echo "no"
- fi
- rm -f _epoll.c _epoll
-fi
-
+# Detect a polling mechanism.
+# See src/eloop.c as to why we only detect ppoll, pollts and pselect and
+# not others like epoll or kqueue.
if [ -z "$POLL" ]; then
printf "Testing for ppoll ... "
cat <<EOF >_ppoll.c
diff --git a/src/eloop.c b/src/eloop.c
index a0581fc4..6785b316 100644
--- a/src/eloop.c
+++ b/src/eloop.c
@@ -26,6 +26,25 @@
* SUCH DAMAGE.
*/
+/* NOTES:
+ * Basically for a small number of fd's (total, not max fd)
+ * of say a few hundred, ppoll(2) performs just fine, if not faster than others.
+ * It also has the smallest memory and binary size footprint.
+ * ppoll(2) is available on all modern OS my software runs on.
+ * If ppoll is not available, then pselect(2) can be used instead.
+ *
+ * Both epoll(7) and kqueue(2) require an extra fd per process to manage
+ * their respective list of interest AND syscalls to manage it.
+ * So for a small number of fd's, these are more resource intensive,
+ * especially when used with more than one process.
+ *
+ * epoll avoids the resource limit RLIMIT_NOFILE Linux poll stupidly applies.
+ * kqueue avoids the same limit on OpenBSD.
+ * ppoll can still be secured in both by using SEECOMP or pledge.
+ *
+ * Taking this all into account, ppoll(2) is the default mechanism used here.
+ */
+
#if (defined(__unix__) || defined(unix)) && !defined(USG)
#include <sys/param.h>
#endif
@@ -51,10 +70,10 @@
#if defined(HAVE_KQUEUE) || defined(HAVE_EPOLL) || defined(HAVE_PPOLL)
#elif defined(HAVE_POLLTS)
#define ppoll pollts
-#elif !defined(HAVE_PSELECT)
-#pragma message("Compiling eloop with pselect(2) support.")
-#define HAVE_PSELECT
+#elif defined(HAVE_PSELECT)
#define ppoll eloop_ppoll
+#else
+#define HAVE_PPOLL
#endif
#if defined(HAVE_KQUEUE)