Author: rjung Date: Sat May 23 12:24:19 2015 New Revision: 1681338 URL: http://svn.apache.org/r1681338 Log: Forward port lots of xies to poll.c from 1.1 to trunk:
r1667243 | markt | 2015-03-17 11:28:05 +0100 (Tue, 17 Mar 2015) | 1 line Follow-up to r1665888. Review by kkolinko. else clause should not depend on s->pe r1665888 | markt | 2015-03-11 15:44:23 +0100 (Wed, 11 Mar 2015) | 1 line Fix 57653. Crash when multiple events for same socket are returned via separate apr_pollfd_t structures r1525525 | rjung | 2013-09-23 10:08:56 +0200 (Mon, 23 Sep 2013) | 6 lines Change return code when removing a socket from a poller, that was actually not in the poller from APR_SUCCESS to APR_NOTFOUND. This lead to corrupt poller handling in the Tomcat APR connector, at least sporadically on Solaris Sparc. r1441792 | mturk | 2013-02-02 20:25:49 +0100 (Sat, 02 Feb 2013) | 1 line Fix BZ55413 by ensuring the returned value is number of event/sockets pairs r1414562 | mturk | 2012-11-28 08:28:20 +0100 (Wed, 28 Nov 2012) | 1 line Fix typo in --enable-maintainer-mode r1414560 | mturk | 2012-11-28 08:19:46 +0100 (Wed, 28 Nov 2012) | 1 line Limit socket to a single instance in the pollset. This allows to optimize remove loop - actually remove it. Modified: tomcat/native/trunk/native/include/tcn.h tomcat/native/trunk/native/src/poll.c Modified: tomcat/native/trunk/native/include/tcn.h URL: http://svn.apache.org/viewvc/tomcat/native/trunk/native/include/tcn.h?rev=1681338&r1=1681337&r2=1681338&view=diff ============================================================================== --- tomcat/native/trunk/native/include/tcn.h (original) +++ tomcat/native/trunk/native/include/tcn.h Sat May 23 12:24:19 2015 @@ -156,6 +156,7 @@ struct tcn_socket_t { char *jsbbuff; char *jrbbuff; tcn_nlayer_t *net; + tcn_pfde_t *pe; apr_time_t last_active; apr_interval_time_t timeout; }; Modified: tomcat/native/trunk/native/src/poll.c URL: http://svn.apache.org/viewvc/tomcat/native/trunk/native/src/poll.c?rev=1681338&r1=1681337&r2=1681338&view=diff ============================================================================== --- tomcat/native/trunk/native/src/poll.c (original) +++ tomcat/native/trunk/native/src/poll.c Sat May 23 12:24:19 2015 @@ -216,6 +216,14 @@ static apr_status_t do_add(tcn_pollset_t #endif return APR_ENOMEM; } + if (s->pe != NULL) { + /* Socket is already added to the pollset. + */ +#ifdef TCN_DO_STATISTICS + p->sp_equals++; +#endif + return APR_EEXIST; + } if (timeout == TCN_NO_SOCKET_TIMEOUT) { timeout = p->default_timeout; } @@ -246,6 +254,7 @@ static apr_status_t do_add(tcn_pollset_t } else { APR_RING_INSERT_TAIL(&p->poll_ring, elem, tcn_pfde_t, link); + s->pe = elem; } return rv; } @@ -275,44 +284,21 @@ TCN_IMPLEMENT_CALL(jint, Poll, addWithTi return (jint) do_add(p, s, (apr_int16_t)reqevents, J2T(socket_timeout)); } -static apr_status_t do_remove(tcn_pollset_t *p, const apr_pollfd_t *fd) -{ - apr_status_t rv; - tcn_pfde_t *ep; - - rv = apr_pollset_remove(p->pollset, fd); - APR_RING_FOREACH(ep, &p->poll_ring, tcn_pfde_t, link) - { - if (fd->desc.s == ep->fd.desc.s) { - APR_RING_REMOVE(ep, link); - APR_RING_INSERT_TAIL(&p->dead_ring, ep, tcn_pfde_t, link); - p->nelts--; -#ifdef TCN_DO_STATISTICS - p->sp_removed++; -#endif - break; - } - } - return rv; -} - -static void update_last_active(tcn_pollset_t *p, const apr_pollfd_t *fd, apr_time_t t) -{ - tcn_socket_t *s = (tcn_socket_t *)fd->client_data; - TCN_ASSERT(s != 0); - s->last_active = t; -} - TCN_IMPLEMENT_CALL(jint, Poll, remove)(TCN_STDARGS, jlong pollset, jlong socket) { apr_pollfd_t fd; + apr_status_t rv; tcn_pollset_t *p = J2P(pollset, tcn_pollset_t *); - tcn_socket_t *s = J2P(socket, tcn_socket_t *); + tcn_socket_t *s = J2P(socket, tcn_socket_t *); UNREFERENCED_STDARGS; TCN_ASSERT(socket != 0); + if (s->pe == NULL) { + /* Already removed */ + return APR_NOTFOUND; + } fd.desc_type = APR_POLL_SOCKET; fd.desc.s = s->sock; fd.client_data = s; @@ -321,7 +307,15 @@ TCN_IMPLEMENT_CALL(jint, Poll, remove)(T p->sp_remove++; #endif - return (jint)do_remove(p, &fd); + rv = apr_pollset_remove(p->pollset, &fd); + APR_RING_REMOVE(s->pe, link); + APR_RING_INSERT_TAIL(&p->dead_ring, s->pe, tcn_pfde_t, link); + s->pe = NULL; + p->nelts--; +#ifdef TCN_DO_STATISTICS + p->sp_removed++; +#endif + return rv; } @@ -350,8 +344,7 @@ TCN_IMPLEMENT_CALL(jint, Poll, poll)(TCN APR_RING_FOREACH(ep, &p->poll_ring, tcn_pfde_t, link) { apr_interval_time_t socket_timeout = 0; - tcn_socket_t *s; - s = (tcn_socket_t *)ep->fd.client_data; + tcn_socket_t *s = (tcn_socket_t *)ep->fd.client_data; if (s->timeout == TCN_NO_SOCKET_TIMEOUT) { socket_timeout = p->default_timeout; } @@ -402,12 +395,33 @@ TCN_IMPLEMENT_CALL(jint, Poll, poll)(TCN if (!remove) now = apr_time_now(); for (i = 0; i < num; i++) { + tcn_socket_t *s = (tcn_socket_t *)fd->client_data; p->set[i*2+0] = (jlong)(fd->rtnevents); - p->set[i*2+1] = P2J(fd->client_data); - if (remove) - do_remove(p, fd); - else - update_last_active(p, fd, now); + p->set[i*2+1] = P2J(s); + /* If a socket is registered for multiple events and the poller has + multiple events to return it may do as a single pair in this + array or as multiple pairs depending on implementation. On OSX at + least, multiple pairs have been observed. In this case do not try + and remove socket from the pollset for a second time else a crash + will result. */ + if (remove) { + if (s->pe) { + apr_pollset_remove(p->pollset, fd); + APR_RING_REMOVE(s->pe, link); + APR_RING_INSERT_TAIL(&p->dead_ring, s->pe, tcn_pfde_t, link); + s->pe = NULL; + p->nelts--; +#ifdef TCN_DO_STATISTICS + p->sp_removed++; +#endif + } + } + else { + /* Update last active with the current time + * after the poll call. + */ + s->last_active = now; + } fd ++; } (*e)->SetLongArrayRegion(e, set, 0, num * 2, p->set); @@ -443,31 +457,35 @@ TCN_IMPLEMENT_CALL(jint, Poll, maintain) } if ((now - s->last_active) >= timeout) { p->set[num++] = P2J(s); - APR_RING_REMOVE(ep, link); - APR_RING_INSERT_TAIL(&p->dead_ring, ep, tcn_pfde_t, link); - p->nelts--; + if (remove) { + APR_RING_REMOVE(ep, link); + APR_RING_INSERT_TAIL(&p->dead_ring, ep, tcn_pfde_t, link); + s->pe = NULL; + p->nelts--; #ifdef TCN_DO_STATISTICS - p->sp_removed++; + p->sp_removed++; #endif + } } } - if (remove && num) { + if (num) { #ifdef TCN_DO_STATISTICS - p->sp_maintained += num; - p->sp_max_maintained = TCN_MAX(p->sp_max_maintained, num); + p->sp_maintained += num; + p->sp_max_maintained = TCN_MAX(p->sp_max_maintained, num); #endif - for (i = 0; i < num; i++) { - apr_pollfd_t fd; - tcn_socket_t *s = J2P(p->set[i], tcn_socket_t *); - fd.desc_type = APR_POLL_SOCKET; - fd.desc.s = s->sock; - fd.client_data = s; - fd.reqevents = APR_POLLIN | APR_POLLOUT; - apr_pollset_remove(p->pollset, &fd); + if (remove) { + for (i = 0; i < num; i++) { + apr_pollfd_t fd; + tcn_socket_t *s = J2P(p->set[i], tcn_socket_t *); + fd.desc_type = APR_POLL_SOCKET; + fd.desc.s = s->sock; + fd.client_data = s; + fd.reqevents = APR_POLLIN | APR_POLLOUT; + apr_pollset_remove(p->pollset, &fd); + } } - } - if (num) (*e)->SetLongArrayRegion(e, set, 0, num, p->set); + } return (jint)num; } @@ -505,7 +523,7 @@ TCN_IMPLEMENT_CALL(jint, Poll, pollset)( } if (n > 0) (*e)->SetLongArrayRegion(e, set, 0, n, p->set); - return n; + return n / 2; } TCN_IMPLEMENT_CALL(jboolean, Poll, wakeable)(TCN_STDARGS, jlong pollset) --------------------------------------------------------------------- To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org For additional commands, e-mail: dev-h...@tomcat.apache.org