Author: markt
Date: Mon Nov 5 00:25:03 2012
New Revision: 1405682
URL: http://svn.apache.org/viewvc?rev=1405682&view=rev
Log:
Fix https://issues.apache.org/bugzilla/show_bug.cgi?id=54086
Ensure only a single thread tries to close the selector. Prior to this change
both the NioReceiverThread and the thread that stops it called closeSelector()
I also reviewed all other accesses to this.selector and fixed a handful of
other potential threading issues.
Modified:
tomcat/tc7.0.x/trunk/ (props changed)
tomcat/tc7.0.x/trunk/java/org/apache/catalina/tribes/transport/ReceiverBase.java
tomcat/tc7.0.x/trunk/java/org/apache/catalina/tribes/transport/nio/NioReceiver.java
tomcat/tc7.0.x/trunk/webapps/docs/changelog.xml
Propchange: tomcat/tc7.0.x/trunk/
------------------------------------------------------------------------------
Merged /tomcat/trunk:r1405681
Modified:
tomcat/tc7.0.x/trunk/java/org/apache/catalina/tribes/transport/ReceiverBase.java
URL:
http://svn.apache.org/viewvc/tomcat/tc7.0.x/trunk/java/org/apache/catalina/tribes/transport/ReceiverBase.java?rev=1405682&r1=1405681&r2=1405682&view=diff
==============================================================================
---
tomcat/tc7.0.x/trunk/java/org/apache/catalina/tribes/transport/ReceiverBase.java
(original)
+++
tomcat/tc7.0.x/trunk/java/org/apache/catalina/tribes/transport/ReceiverBase.java
Mon Nov 5 00:25:03 2012
@@ -63,7 +63,7 @@ public abstract class ReceiverBase imple
private int udpRxBufSize = 43800;
private int udpTxBufSize = 25188;
- private boolean listen = false;
+ private volatile boolean listen = false;
private RxTaskPool pool;
private boolean direct = true;
private long tcpSelectorTimeout = 5000;
Modified:
tomcat/tc7.0.x/trunk/java/org/apache/catalina/tribes/transport/nio/NioReceiver.java
URL:
http://svn.apache.org/viewvc/tomcat/tc7.0.x/trunk/java/org/apache/catalina/tribes/transport/nio/NioReceiver.java?rev=1405682&r1=1405681&r2=1405682&view=diff
==============================================================================
---
tomcat/tc7.0.x/trunk/java/org/apache/catalina/tribes/transport/nio/NioReceiver.java
(original)
+++
tomcat/tc7.0.x/trunk/java/org/apache/catalina/tribes/transport/nio/NioReceiver.java
Mon Nov 5 00:25:03 2012
@@ -30,6 +30,7 @@ import java.nio.channels.SocketChannel;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.Set;
+import java.util.concurrent.atomic.AtomicReference;
import org.apache.catalina.tribes.io.ObjectReader;
import org.apache.catalina.tribes.transport.AbstractRxTask;
@@ -58,7 +59,7 @@ public class NioReceiver extends Receive
*/
private static final String info = "NioReceiver/1.0";
- private Selector selector = null;
+ private AtomicReference<Selector> selector = new
AtomicReference<Selector>();
private ServerSocketChannel serverChannel = null;
private DatagramChannel datagramChannel = null;
@@ -136,7 +137,7 @@ public class NioReceiver extends Receive
// Selector.open() isn't thread safe
// http://bugs.sun.com/view_bug.do?bug_id=6427854
// Affects 1.6.0_29, fixed in 1.7.0_01
- selector = Selector.open();
+ this.selector.set(Selector.open());
}
// set the port the server channel will listen to
//serverSocket.bind(new InetSocketAddress(getBind(),
getTcpListenPort()));
@@ -144,7 +145,7 @@ public class NioReceiver extends Receive
// set non-blocking mode for the listening socket
serverChannel.configureBlocking(false);
// register the ServerSocketChannel with the Selector
- serverChannel.register(selector, SelectionKey.OP_ACCEPT);
+ serverChannel.register(this.selector.get(), SelectionKey.OP_ACCEPT);
//set up the datagram channel
if (this.getUdpPort()>0) {
@@ -165,12 +166,13 @@ public class NioReceiver extends Receive
}
public void addEvent(Runnable event) {
+ Selector selector = this.selector.get();
if ( selector != null ) {
synchronized (events) {
events.add(event);
}
if ( log.isTraceEnabled() ) log.trace("Adding event to
selector:"+event);
- if ( isListening() && selector!=null ) selector.wakeup();
+ if ( isListening() ) selector.wakeup();
}
}
@@ -210,7 +212,7 @@ public class NioReceiver extends Receive
long now = System.currentTimeMillis();
if ( (now-lastCheck) < getSelectorTimeout() ) return;
//timeout
- Selector tmpsel = selector;
+ Selector tmpsel = this.selector.get();
Set<SelectionKey> keys =
(isListening()&&tmpsel!=null)?tmpsel.keys():null;
if ( keys == null ) return;
for (Iterator<SelectionKey> iter = keys.iterator(); iter.hasNext();) {
@@ -263,7 +265,7 @@ public class NioReceiver extends Receive
setListen(true);
// Avoid NPEs if selector is set to null on stop.
- Selector selector = this.selector;
+ Selector selector = this.selector.get();
if (selector!=null && datagramChannel!=null) {
ObjectReader oreader = new ObjectReader(MAX_UDP_SIZE); //max size
for a datagram packet
@@ -359,6 +361,7 @@ public class NioReceiver extends Receive
*/
protected void stopListening() {
setListen(false);
+ Selector selector = this.selector.get();
if (selector != null) {
try {
selector.wakeup();
@@ -366,14 +369,13 @@ public class NioReceiver extends Receive
} catch (Exception x) {
log.error("Unable to close cluster receiver selector.", x);
} finally {
- selector = null;
+ this.selector.set(null);
}
}
}
private void closeSelector() throws IOException {
- Selector selector = this.selector;
- this.selector = null;
+ Selector selector = this.selector.getAndSet(null);
if (selector==null) return;
try {
Iterator<SelectionKey> it = selector.keys().iterator();
Modified: tomcat/tc7.0.x/trunk/webapps/docs/changelog.xml
URL:
http://svn.apache.org/viewvc/tomcat/tc7.0.x/trunk/webapps/docs/changelog.xml?rev=1405682&r1=1405681&r2=1405682&view=diff
==============================================================================
--- tomcat/tc7.0.x/trunk/webapps/docs/changelog.xml (original)
+++ tomcat/tc7.0.x/trunk/webapps/docs/changelog.xml Mon Nov 5 00:25:03 2012
@@ -171,6 +171,10 @@
Add getSessionIdsFull operation to mbeans-descriptor.
listSessionIdsFull
no longer exist. (kfujino)
</fix>
+ <fix>
+ <bug>54086</bug>: Fix threading issue when stopping an
+ <code>NioReceiver</code>. (markt)
+ </fix>
</changelog>
</subsection>
<subsection name="Tribes">
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]