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: [email protected]
For additional commands, e-mail: [email protected]