aboutsummaryrefslogtreecommitdiff
path: root/devel/apr1
diff options
context:
space:
mode:
authorOlli Hauer <ohauer@FreeBSD.org>2016-08-04 18:44:21 +0000
committerOlli Hauer <ohauer@FreeBSD.org>2016-08-04 18:44:21 +0000
commit1bec1395d97ac7cd576ee3b5808cc7ca70f05120 (patch)
tree1773d2872ca9269e9321e9a1c25691064302da61 /devel/apr1
parent06719e2885bbe96b18b4891a22df2f80a1b30fdf (diff)
downloadports-1bec1395d97ac7cd576ee3b5808cc7ca70f05120.tar.gz
ports-1bec1395d97ac7cd576ee3b5808cc7ca70f05120.zip
- add patch to modify apr1 poll() emulation to match behavior expected by serf
serf depends on the poll emulation in apr returning a POLLERR event if a non-blocking connect() attempt fails in order to trigger an IPv6 -> IPv4 fallback, or a fallback to another address for a multi-homed host. On FreeBSD, the poll emulation is done using kqueue, and the result returned by the poll() emulation is POLLIN + POLLHUP. - upstream apache PR: https://bz.apache.org/bugzilla/show_bug.cgi?id=59914 PR: 211430 Submitted by: Don Lewis (truckman@) MFH: 2016Q3
Notes
Notes: svn path=/head/; revision=419646
Diffstat (limited to 'devel/apr1')
-rw-r--r--devel/apr1/Makefile1
-rw-r--r--devel/apr1/files/patch-apr_poll_unix_kqueue.c77
2 files changed, 78 insertions, 0 deletions
diff --git a/devel/apr1/Makefile b/devel/apr1/Makefile
index 529f47e09733..4b1a6def5bb2 100644
--- a/devel/apr1/Makefile
+++ b/devel/apr1/Makefile
@@ -3,6 +3,7 @@
PORTNAME= apr
PORTVERSION= ${APR_VERSION}.${APU_VERSION}
+PORTREVISION= 1
CATEGORIES= devel
MASTER_SITES= APACHE/apr
DISTFILES= apr-${APR_VERSION}.tar.gz \
diff --git a/devel/apr1/files/patch-apr_poll_unix_kqueue.c b/devel/apr1/files/patch-apr_poll_unix_kqueue.c
new file mode 100644
index 000000000000..c34d92ca78d1
--- /dev/null
+++ b/devel/apr1/files/patch-apr_poll_unix_kqueue.c
@@ -0,0 +1,77 @@
+# upstram PR: https://bz.apache.org/bugzilla/show_bug.cgi?id=59914
+# FreeBSD PR: 211430
+========================================================================
+--- apr-1.5.2/poll/unix/kqueue.c.orig 2015-03-20 01:34:07 UTC
++++ apr-1.5.2/poll/unix/kqueue.c
+@@ -25,21 +25,40 @@
+
+ #ifdef HAVE_KQUEUE
+
+-static apr_int16_t get_kqueue_revent(apr_int16_t event, apr_int16_t flags)
++static apr_int16_t get_kqueue_revent(apr_int16_t event, apr_int16_t flags,
++ int fflags, intptr_t data)
+ {
+ apr_int16_t rv = 0;
+
+- if (event == EVFILT_READ)
+- rv |= APR_POLLIN;
+- else if (event == EVFILT_WRITE)
+- rv |= APR_POLLOUT;
+- if (flags & EV_EOF)
+- rv |= APR_POLLHUP;
+- /* APR_POLLPRI, APR_POLLERR, and APR_POLLNVAL are not handled by this
+- * implementation.
++ /* APR_POLLPRI and APR_POLLNVAL are not handled by this implementation.
+ * TODO: See if EV_ERROR + certain system errors in the returned data field
+ * should map to APR_POLLNVAL.
+ */
++ if (event == EVFILT_READ) {
++ if (data > 0 || fflags == 0)
++ rv |= APR_POLLIN;
++ else
++ rv |= APR_POLLERR;
++ /*
++ * Don't return POLLHUP if connect fails. Apparently Linux
++ * does not, and this is expected by serf in order for IPv6 to
++ * IPv4 or multihomed host fallback to work.
++ *
++ * ETIMEDOUT is ambiguous here since we don't know if a
++ * connection was established. We don't want to return
++ * POLLHUP here if the connection attempt timed out, but
++ * we do if the connection was successful but later dropped.
++ * For now, favor the latter.
++ */
++ if ((flags & EV_EOF) != 0 && fflags != ECONNREFUSED &&
++ fflags != ENETUNREACH && fflags != EHOSTUNREACH)
++ rv |= APR_POLLHUP;
++ } else if (event == EVFILT_WRITE) {
++ if (data > 0 || fflags == 0)
++ rv |= APR_POLLOUT;
++ else
++ rv |= APR_POLLERR;
++ }
+ return rv;
+ }
+
+@@ -290,7 +309,9 @@ static apr_status_t impl_pollset_poll(ap
+ pollset->p->result_set[j] = fd;
+ pollset->p->result_set[j].rtnevents =
+ get_kqueue_revent(pollset->p->ke_set[i].filter,
+- pollset->p->ke_set[i].flags);
++ pollset->p->ke_set[i].flags,
++ pollset->p->ke_set[i].fflags,
++ pollset->p->ke_set[i].data);
+ j++;
+ }
+ }
+@@ -471,7 +492,9 @@ static apr_status_t impl_pollcb_poll(apr
+ apr_pollfd_t *pollfd = (apr_pollfd_t *)(pollcb->pollset.ke[i].udata);
+
+ pollfd->rtnevents = get_kqueue_revent(pollcb->pollset.ke[i].filter,
+- pollcb->pollset.ke[i].flags);
++ pollcb->pollset.ke[i].flags,
++ pollcb->pollset.ke[i].fflags,
++ pollcb->pollset.ke[i].data);
+
+ rv = func(baton, pollfd);
+