Author: mturk Date: Fri Nov 23 15:44:27 2012 New Revision: 1412919 URL: http://svn.apache.org/viewvc?rev=1412919&view=rev Log: Use apr_ring instead array for maintaining pollset
Modified: tomcat/native/branches/1.1.x/native/include/tcn.h tomcat/native/branches/1.1.x/native/src/network.c tomcat/native/branches/1.1.x/native/src/poll.c Modified: tomcat/native/branches/1.1.x/native/include/tcn.h URL: http://svn.apache.org/viewvc/tomcat/native/branches/1.1.x/native/include/tcn.h?rev=1412919&r1=1412918&r2=1412919&view=diff ============================================================================== --- tomcat/native/branches/1.1.x/native/include/tcn.h (original) +++ tomcat/native/branches/1.1.x/native/include/tcn.h Fri Nov 23 15:44:27 2012 @@ -30,6 +30,7 @@ #include "apr_portable.h" #include "apr_network_io.h" #include "apr_poll.h" +#include "apr_ring.h" #include "apr_strings.h" #ifndef APR_HAS_THREADS @@ -145,7 +146,15 @@ typedef struct { apr_status_t (APR_THREAD_FUNC *recv) (apr_socket_t *, char *, apr_size_t *); } tcn_nlayer_t; -typedef struct { +typedef struct tcn_socket_t tcn_socket_t; +typedef struct tcn_pfde_t tcn_pfde_t; + +struct tcn_pfde_t { + APR_RING_ENTRY(tcn_pfde_t) link; + apr_pollfd_t fd; +}; + +struct tcn_socket_t { apr_pool_t *pool; apr_pool_t *child; apr_socket_t *sock; @@ -155,8 +164,7 @@ typedef struct { tcn_nlayer_t *net; apr_time_t last_active; apr_interval_time_t timeout; - apr_pollfd_t fd; -} tcn_socket_t; +}; /* Private helper functions */ void tcn_Throw(JNIEnv *, const char *, ...); Modified: tomcat/native/branches/1.1.x/native/src/network.c URL: http://svn.apache.org/viewvc/tomcat/native/branches/1.1.x/native/src/network.c?rev=1412919&r1=1412918&r2=1412919&view=diff ============================================================================== --- tomcat/native/branches/1.1.x/native/src/network.c (original) +++ tomcat/native/branches/1.1.x/native/src/network.c Fri Nov 23 15:44:27 2012 @@ -207,9 +207,6 @@ TCN_IMPLEMENT_CALL(jlong, Socket, create if (family >= 0) a->net = &apr_socket_layer; a->opaque = s; - a->fd.desc_type = APR_POLL_SOCKET; - a->fd.desc.s = a->sock; - a->fd.client_data = a; return P2J(a); cleanup: if (c) @@ -369,9 +366,6 @@ TCN_IMPLEMENT_CALL(jlong, Socket, accept a->net = &apr_socket_layer; a->sock = n; a->opaque = n; - a->fd.desc_type = APR_POLL_SOCKET; - a->fd.desc.s = a->sock; - a->fd.client_data = a; } cleanup: @@ -412,9 +406,6 @@ TCN_IMPLEMENT_CALL(jlong, Socket, accept a->net = &apr_socket_layer; a->sock = n; a->opaque = n; - a->fd.desc_type = APR_POLL_SOCKET; - a->fd.desc.s = a->sock; - a->fd.client_data = a; } return P2J(a); cleanup: Modified: tomcat/native/branches/1.1.x/native/src/poll.c URL: http://svn.apache.org/viewvc/tomcat/native/branches/1.1.x/native/src/poll.c?rev=1412919&r1=1412918&r2=1412919&view=diff ============================================================================== --- tomcat/native/branches/1.1.x/native/src/poll.c (original) +++ tomcat/native/branches/1.1.x/native/src/poll.c Fri Nov 23 15:44:27 2012 @@ -30,15 +30,23 @@ static int sp_cleared = 0; /* Internal poll structure for queryset */ - typedef struct tcn_pollset { apr_pool_t *pool; apr_int32_t nelts; apr_int32_t nalloc; apr_pollset_t *pollset; jlong *set; - apr_pollfd_t **socket_set; apr_interval_time_t default_timeout; + /* A ring containing all of the pollfd_t that are active + */ + APR_RING_HEAD(pfd_poll_ring_t, tcn_pfde_t) poll_ring; + /* A ring of pollfd_t that have been used, and then _remove()'d + */ + APR_RING_HEAD(pfd_free_ring_t, tcn_pfde_t) free_ring; + /* A ring of pollfd_t where rings that have been _remove()`ed but + * might still be inside a _poll() + */ + APR_RING_HEAD(pfd_dead_ring_t, tcn_pfde_t) dead_ring; #ifdef TCN_DO_STATISTICS int sp_added; int sp_max_count; @@ -121,10 +129,12 @@ TCN_IMPLEMENT_CALL(jlong, Poll, create)( tps = apr_pcalloc(p, sizeof(tcn_pollset_t)); TCN_CHECK_ALLOCATED(tps); tps->pollset = pollset; - tps->set = apr_palloc(p, size * sizeof(jlong) * 2); + tps->set = apr_pcalloc(p, size * sizeof(jlong) * 2); TCN_CHECK_ALLOCATED(tps->set); - tps->socket_set = apr_palloc(p, size * sizeof(apr_pollfd_t *)); - TCN_CHECK_ALLOCATED(tps->socket_set); + APR_RING_INIT(&tps->poll_ring, tcn_pfde_t, link); + APR_RING_INIT(&tps->free_ring, tcn_pfde_t, link); + APR_RING_INIT(&tps->dead_ring, tcn_pfde_t, link); + tps->nelts = 0; tps->nalloc = size; tps->pool = p; @@ -155,9 +165,13 @@ TCN_IMPLEMENT_CALL(jint, Poll, destroy)( static apr_status_t do_add(tcn_pollset_t *p, tcn_socket_t *s, apr_int16_t reqevents, - apr_interval_time_t socket_timeout) { + apr_interval_time_t socket_timeout) +{ + apr_int32_t i; + apr_status_t rv; apr_interval_time_t timeout = socket_timeout; + tcn_pfde_t *elem = NULL; if (p->nelts == p->nalloc) { #ifdef TCN_DO_STATISTICS @@ -173,15 +187,30 @@ static apr_status_t do_add(tcn_pollset_t else s->last_active = 0; s->timeout = socket_timeout; - s->fd.reqevents = reqevents; - - p->socket_set[p->nelts] = &s->fd; - p->nelts++; + if (!APR_RING_EMPTY(&p->free_ring, tcn_pfde_t, link)) { + elem = APR_RING_FIRST(&p->free_ring); + APR_RING_REMOVE(elem, link); + } + else { + elem = (tcn_pfde_t *)apr_palloc(p->pool, sizeof(tcn_pfde_t)); + APR_RING_ELEM_INIT(elem, link); + } + elem->fd.reqevents = reqevents; + elem->fd.desc_type = APR_POLL_SOCKET; + elem->fd.desc.s = s->sock; + elem->fd.client_data = s; #ifdef TCN_DO_STATISTICS p->sp_added++; p->sp_max_count = TCN_MAX(p->sp_max_count, p->sp_added); #endif - return (jint)apr_pollset_add(p->pollset, &s->fd); + rv = apr_pollset_add(p->pollset, &elem->fd); + if (rv != APR_SUCCESS) { + APR_RING_INSERT_TAIL(&p->free_ring, elem, tcn_pfde_t, link); + } + else { + APR_RING_INSERT_TAIL(&p->poll_ring, elem, tcn_pfde_t, link); + } + return rv; } TCN_IMPLEMENT_CALL(jint, Poll, add)(TCN_STDARGS, jlong pollset, @@ -211,46 +240,33 @@ TCN_IMPLEMENT_CALL(jint, Poll, addWithTi static apr_status_t do_remove(tcn_pollset_t *p, const apr_pollfd_t *fd) { - apr_int32_t i; + apr_status_t rv; + tcn_pfde_t *ep; - for (i = 0; i < p->nelts; i++) { - if (fd->desc.s == p->socket_set[i]->desc.s) { - /* Found an instance of the fd: remove this and any other copies */ - apr_int32_t dst = i; - apr_int32_t old_nelts = p->nelts; - tcn_socket_t *ds = (tcn_socket_t *)p->socket_set[dst]->client_data; + 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 - for (i++; i < old_nelts; i++) { - tcn_socket_t *ss = (tcn_socket_t *)p->socket_set[i]->client_data; - if (fd->desc.s == p->socket_set[i]->desc.s) { -#ifdef TCN_DO_STATISTICS - p->sp_equals++; -#endif - p->nelts--; - } - else { - p->socket_set[dst] = p->socket_set[i]; - ds->last_active = ss->last_active; - ds->timeout = ss->timeout; - ds = (tcn_socket_t *)p->socket_set[++dst]->client_data; - } - } break; } } - return apr_pollset_remove(p->pollset, fd); + return rv; } static void update_last_active(tcn_pollset_t *p, const apr_pollfd_t *fd, apr_time_t t) { - apr_int32_t i; + tcn_pfde_t *ep; - for (i = 0; i < p->nelts; i++) { - if (fd->desc.s == p->socket_set[i]->desc.s) { - tcn_socket_t *s = (tcn_socket_t *)p->socket_set[i]->client_data; + APR_RING_FOREACH(ep, &p->poll_ring, tcn_pfde_t, link) + { + if (fd->desc.s == ep->fd.desc.s) { + tcn_socket_t *s = (tcn_socket_t *)ep->fd.client_data; /* Found an instance of the fd: update last active time */ s->last_active = t; break; @@ -262,18 +278,22 @@ static void update_last_active(tcn_polls TCN_IMPLEMENT_CALL(jint, Poll, remove)(TCN_STDARGS, jlong pollset, jlong socket) { + apr_pollfd_t fd; tcn_pollset_t *p = J2P(pollset, tcn_pollset_t *); tcn_socket_t *s = J2P(socket, tcn_socket_t *); UNREFERENCED_STDARGS; TCN_ASSERT(socket != 0); - s->fd.reqevents = APR_POLLIN | APR_POLLOUT; + fd.desc_type = APR_POLL_SOCKET; + fd.desc.s = s->sock; + fd.client_data = s; + fd.reqevents = APR_POLLIN | APR_POLLOUT; #ifdef TCN_DO_STATISTICS p->sp_remove++; #endif - return (jint)do_remove(p, &s->fd); + return (jint)do_remove(p, &fd); } @@ -295,12 +315,15 @@ TCN_IMPLEMENT_CALL(jint, Poll, poll)(TCN #endif if (ptime > 0) { - now = apr_time_now(); + tcn_pfde_t *ep; + now = apr_time_now(); /* Find the minimum timeout */ - for (i = 0; i < p->nelts; i++) { + APR_RING_FOREACH(ep, &p->poll_ring, tcn_pfde_t, link) + { apr_interval_time_t socket_timeout = 0; - tcn_socket_t *s = (tcn_socket_t *)p->socket_set[i]->client_data; + tcn_socket_t *s; + s = (tcn_socket_t *)ep->fd.client_data; if (s->timeout == TCN_NO_SOCKET_TIMEOUT) { socket_timeout = p->default_timeout; } @@ -341,6 +364,8 @@ TCN_IMPLEMENT_CALL(jint, Poll, poll)(TCN } break; } + /* Shift all PFDs in the Dead Ring to the Free Ring */ + APR_RING_CONCAT(&p->free_ring, &p->dead_ring, tcn_pfde_t, link); if (num > 0) { #ifdef TCN_DO_STATISTICS p->sp_polled += num; @@ -369,15 +394,16 @@ TCN_IMPLEMENT_CALL(jint, Poll, maintain) tcn_pollset_t *p = J2P(pollset, tcn_pollset_t *); apr_int32_t i = 0, num = 0; apr_time_t now = apr_time_now(); - apr_pollfd_t *fd; + tcn_pfde_t *ep, *ip; UNREFERENCED(o); TCN_ASSERT(pollset != 0); /* Check for timeout sockets */ - for (i = 0; i < p->nelts; i++) { + APR_RING_FOREACH_SAFE(ep, ip, &p->poll_ring, tcn_pfde_t, link) + { apr_interval_time_t timeout = 0; - tcn_socket_t *s = (tcn_socket_t *)p->socket_set[i]->client_data; + tcn_socket_t *s = (tcn_socket_t *)ep->fd.client_data; if (s->timeout == TCN_NO_SOCKET_TIMEOUT) { timeout = p->default_timeout; } @@ -389,6 +415,12 @@ 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--; +#ifdef TCN_DO_STATISTICS + p->sp_removed++; +#endif } } if (remove && num) { @@ -397,9 +429,13 @@ TCN_IMPLEMENT_CALL(jint, Poll, maintain) p->sp_max_maintained = TCN_MAX(p->sp_max_maintained, num); #endif for (i = 0; i < num; i++) { - fd = &(J2P(p->set[i], tcn_socket_t *)->fd); - fd->reqevents = APR_POLLIN | APR_POLLOUT; - do_remove(p, fd); + 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) @@ -426,19 +462,20 @@ TCN_IMPLEMENT_CALL(jint, Poll, pollset)( jlongArray set) { tcn_pollset_t *p = J2P(pollset, tcn_pollset_t *); - apr_int32_t i = 0; - apr_pollfd_t *fd; + apr_int32_t n = 0; + tcn_pfde_t *ep; UNREFERENCED(o); TCN_ASSERT(pollset != 0); - for (i = 0; i < p->nelts; i++) { - p->socket_set[i]->rtnevents = APR_POLLHUP | APR_POLLIN; - fd = p->socket_set[i]; - p->set[i*2+0] = (jlong)(fd->rtnevents); - p->set[i*2+1] = P2J(fd->client_data); - } - if (p->nelts) - (*e)->SetLongArrayRegion(e, set, 0, p->nelts * 2, p->set); - return (jint)p->nelts; + APR_RING_FOREACH(ep, &p->poll_ring, tcn_pfde_t, link) + { + apr_pollfd_t *fd = &ep->fd; + fd->rtnevents = APR_POLLHUP | APR_POLLIN; + p->set[n++] = (jlong)(fd->rtnevents); + p->set[n++] = P2J(fd->client_data); + } + if (n > 0) + (*e)->SetLongArrayRegion(e, set, 0, n, p->set); + return n; } --------------------------------------------------------------------- To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org For additional commands, e-mail: dev-h...@tomcat.apache.org