Line 0
Link Here
|
|
|
1 |
--- apr-1.5.2/poll/unix/kqueue.c.orig 2015-03-20 01:34:07 UTC |
2 |
+++ apr-1.5.2/poll/unix/kqueue.c |
3 |
@@ -25,21 +25,40 @@ |
4 |
|
5 |
#ifdef HAVE_KQUEUE |
6 |
|
7 |
-static apr_int16_t get_kqueue_revent(apr_int16_t event, apr_int16_t flags) |
8 |
+static apr_int16_t get_kqueue_revent(apr_int16_t event, apr_int16_t flags, |
9 |
+ int fflags, intptr_t data) |
10 |
{ |
11 |
apr_int16_t rv = 0; |
12 |
|
13 |
- if (event == EVFILT_READ) |
14 |
- rv |= APR_POLLIN; |
15 |
- else if (event == EVFILT_WRITE) |
16 |
- rv |= APR_POLLOUT; |
17 |
- if (flags & EV_EOF) |
18 |
- rv |= APR_POLLHUP; |
19 |
- /* APR_POLLPRI, APR_POLLERR, and APR_POLLNVAL are not handled by this |
20 |
- * implementation. |
21 |
+ /* APR_POLLPRI and APR_POLLNVAL are not handled by this implementation. |
22 |
* TODO: See if EV_ERROR + certain system errors in the returned data field |
23 |
* should map to APR_POLLNVAL. |
24 |
*/ |
25 |
+ if (event == EVFILT_READ) { |
26 |
+ if (data > 0 || fflags == 0) |
27 |
+ rv |= APR_POLLIN; |
28 |
+ else |
29 |
+ rv |= APR_POLLERR; |
30 |
+ /* |
31 |
+ * Don't return POLLHUP if connect fails. Apparently Linux |
32 |
+ * does not, and this is expected by serf in order for IPv6 to |
33 |
+ * IPv4 or multihomed host fallback to work. |
34 |
+ * |
35 |
+ * ETIMEDOUT is ambiguous here since we don't know if a |
36 |
+ * connection was established. We don't want to return |
37 |
+ * POLLHUP here if the connection attempt timed out, but |
38 |
+ * we do if the connection was successful but later dropped. |
39 |
+ * For now, favor the latter. |
40 |
+ */ |
41 |
+ if ((flags & EV_EOF) != 0 && fflags != ECONNREFUSED && |
42 |
+ fflags != ENETUNREACH && fflags != EHOSTUNREACH) |
43 |
+ rv |= APR_POLLHUP; |
44 |
+ } else if (event == EVFILT_WRITE) { |
45 |
+ if (data > 0 || fflags == 0) |
46 |
+ rv |= APR_POLLOUT; |
47 |
+ else |
48 |
+ rv |= APR_POLLERR; |
49 |
+ } |
50 |
return rv; |
51 |
} |
52 |
|
53 |
@@ -290,7 +309,9 @@ static apr_status_t impl_pollset_poll(ap |
54 |
pollset->p->result_set[j] = fd; |
55 |
pollset->p->result_set[j].rtnevents = |
56 |
get_kqueue_revent(pollset->p->ke_set[i].filter, |
57 |
- pollset->p->ke_set[i].flags); |
58 |
+ pollset->p->ke_set[i].flags, |
59 |
+ pollset->p->ke_set[i].fflags, |
60 |
+ pollset->p->ke_set[i].data); |
61 |
j++; |
62 |
} |
63 |
} |
64 |
@@ -471,7 +492,9 @@ static apr_status_t impl_pollcb_poll(apr |
65 |
apr_pollfd_t *pollfd = (apr_pollfd_t *)(pollcb->pollset.ke[i].udata); |
66 |
|
67 |
pollfd->rtnevents = get_kqueue_revent(pollcb->pollset.ke[i].filter, |
68 |
- pollcb->pollset.ke[i].flags); |
69 |
+ pollcb->pollset.ke[i].flags, |
70 |
+ pollcb->pollset.ke[i].fflags, |
71 |
+ pollcb->pollset.ke[i].data); |
72 |
|
73 |
rv = func(baton, pollfd); |
74 |
|