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

Reply via email to