You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tomcat.apache.org by ma...@apache.org on 2013/09/25 01:50:10 UTC
svn commit: r1526052 -
/tomcat/trunk/java/org/apache/tomcat/util/net/AprEndpoint.java
Author: markt
Date: Tue Sep 24 23:50:09 2013
New Revision: 1526052
URL: http://svn.apache.org/r1526052
Log:
Removal of a socket from the poller needs to happen on the poller thread as removal, like addition, is not thread safe.
Removal of a socket from the poller needs to remove the socket from the addListif it is present otherwise the closed socket could end up in the poller.
Modified:
tomcat/trunk/java/org/apache/tomcat/util/net/AprEndpoint.java
Modified: tomcat/trunk/java/org/apache/tomcat/util/net/AprEndpoint.java
URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/tomcat/util/net/AprEndpoint.java?rev=1526052&r1=1526051&r2=1526052&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/tomcat/util/net/AprEndpoint.java (original)
+++ tomcat/trunk/java/org/apache/tomcat/util/net/AprEndpoint.java Tue Sep 24 23:50:09 2013
@@ -907,7 +907,7 @@ public class AprEndpoint extends Abstrac
// countDownConnection() in that case
Poller poller = this.poller;
if (poller != null) {
- poller.removeFromPoller(socket);
+ poller.remove(socket);
}
connections.remove(Long.valueOf(socket));
destroySocket(socket, running);
@@ -1220,6 +1220,19 @@ public class AprEndpoint extends Abstrac
}
}
+ public boolean remove(long socket) {
+ for (int i = 0; i < size; i++) {
+ if (sockets[i] == socket) {
+ sockets[i] = sockets[size - 1];
+ timeouts[i] = timeouts[size - 1];
+ flags[size] = flags[size -1];
+ size--;
+ return true;
+ }
+ }
+ return false;
+ }
+
public void duplicate(SocketList copy) {
copy.size = size;
copy.pos = pos;
@@ -1276,6 +1289,12 @@ public class AprEndpoint extends Abstrac
/**
+ * List of sockets to be removed from the poller.
+ */
+ private SocketList removeList = null;
+
+
+ /**
* Structure used for storing timeouts.
*/
private SocketTimeouts timeouts = null;
@@ -1349,6 +1368,7 @@ public class AprEndpoint extends Abstrac
desc = new long[actualPollerSize * 2];
connectionCount = 0;
addList = new SocketList(defaultPollerSize);
+ removeList = new SocketList(defaultPollerSize);
}
@@ -1464,8 +1484,10 @@ public class AprEndpoint extends Abstrac
}
}
+
/**
- * Add specified socket to one of the pollers.
+ * Add specified socket to one of the pollers. Must only be called from
+ * {@link Poller#run()}.
*/
private boolean addToPoller(long socket, int events) {
int rv = -1;
@@ -1482,10 +1504,19 @@ public class AprEndpoint extends Abstrac
return false;
}
+
+ protected void remove(long socket) {
+ synchronized (this) {
+ removeList.add(socket, 0, 0);
+ }
+ }
+
+
/**
- * Remove specified socket from the pollers.
+ * Remove specified socket from the pollers. Must only be called from
+ * {@link Poller#run()}.
*/
- protected boolean removeFromPoller(long socket) {
+ private boolean removeFromPoller(long socket) {
int rv = -1;
for (int i = 0; i < pollers.length; i++) {
if (pollerSpace[i] < actualPollerSize) {
@@ -1560,7 +1591,7 @@ public class AprEndpoint extends Abstrac
int maintain = 0;
SocketList localAddList = new SocketList(getMaxConnections());
-
+ SocketList localRemoveList = new SocketList(getMaxConnections());
// Loop until we receive a shutdown command
while (pollerRunning) {
@@ -1598,7 +1629,18 @@ public class AprEndpoint extends Abstrac
}
try {
- // Add sockets which are waiting to the poller
+ // Duplicate the add and remove lists so that the syncs are
+ // minimised
+ if (removeList.size() > 0) {
+ synchronized (this) {
+ // Duplicate to another list, so that the syncing is
+ // minimal
+ removeList.duplicate(localRemoveList);
+ removeList.clear();
+ }
+ } else {
+ localAddList.clear();
+ }
if (addList.size() > 0) {
synchronized (this) {
// Duplicate to another list, so that the syncing is
@@ -1606,6 +1648,22 @@ public class AprEndpoint extends Abstrac
addList.duplicate(localAddList);
addList.clear();
}
+ } else {
+ localAddList.clear();
+ }
+
+ // Remove sockets
+ if (localRemoveList.size() > 0) {
+ SocketInfo info = localRemoveList.get();
+ while (info != null) {
+ localAddList.remove(info.socket);
+ removeFromPoller(info.socket);
+ info = localRemoveList.get();
+ }
+ }
+
+ // Add sockets which are waiting to the poller
+ if (localAddList.size() > 0) {
SocketInfo info = localAddList.get();
while (info != null) {
if (log.isDebugEnabled()) {
---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@tomcat.apache.org
For additional commands, e-mail: dev-help@tomcat.apache.org